Tag Archives: PowerShell

PowerShell: Read hashtable from a file

Had a file with the following kind of data.

10.0.0.1=alice.example.com
10.0.0.2=bob.example.com

Wanted to read this in as a hashtable so that I could use it for lookup in a script. Tried doing the following, but ended up with an array of hashtables instead of one hashtable. This is because Get-Content by default actually gives you an array of lines, which are then piped into ConvertFrom-StringData one by one.

PS> Get-Content .\hostnames.txt | ConvertFrom-StringData
PS> $names.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS> $names[0].GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object

Turns out it was easy to fix by adding the -raw parameter.

PS> $names = Get-Content -raw .\hostnames.txt | ConvertFrom-StringData
PS> $names.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Hashtable                                System.Object

PS> $names['10.0.0.1']
alice.example.com

PowerShell: Parse, sort, filter and add to a CSV

Made an export from Splunk containing all IP addresses who had called a method on a companies ESB servers. This gave me a large CSV with two columns, Method and IP, which I then needed to filter to remove duplicate rows. Additionally I wanted to try a reverse lookup of the address to identify what system in our environment was actually doing the call us.

Import-Csv .\requests.csv |
sort Method,IP -Unique |
select *,@{Name="Host";Expression={[Net.Dns]::GetHostEntry($_.IP).HostName}}
Export-Csv .\requests-filtered.csv

Most lines should be self-explanatory, but the neat bit is the select statement. I use the * to select all existing properties, and then I use a nutty syntax I learned today to add a calculated property.

Pretty neat. Worked great, with the exception that every IP was resolvable, but’s the fault of the DNS server at the company… 🙂

PowerShell: Write stuff to an XML file

Needed to recursively list all the files of a certain type and save them as an XML file. Turns out this was pretty easy using PowerShell.

# Make a regular .Net XmlTextWriter
$output = "processes.xml";
$xml = New-Object System.Xml.XmlTextWriter($output, $Null);
$xml.Formatting = "Indented"
$xml.IndentChar = " ";
$xml.Indentation = "1";

# Start writing
$xml.WriteStartDocument();
$xml.WriteStartElement("root");

# Do the listing and keep outputting XML
Get-ChildItem .. -Recurse -include *.esbp |
foreach {
    $name = $_.BaseName;
    $path = Resolve-Path $_ -relative;

    $xml.WriteStartElement("process");
    $xml.WriteAttributeString("id", $name);
    $xml.WriteString($path);
    $xml.WriteEndElement();
}

# Close the writer, which also closes the root element and document for us
$xml.Close();

Easy peasy!

How to run PowerShell scripts directly from Windows command line

If you find yourself in the regular command line (cmd.exe) on Windows and you’d like to run a PowerShell script, you can do it like this:

> powershell ./example-script.ps1

Would be nice if you could just run it directly as a bat file though, right? And yes, you can! Continue reading How to run PowerShell scripts directly from Windows command line

PowerShell: Run command for each directory

I wanted to run the svn update command for each directory in my Eclipse workspace. Could be done like this:

PS C:\workspace> Get-ChildItem |
where {$_.PsIsContainer} |
foreach {svn update $_.name}

This gets all child items (files and directories) in the workspace folder, filters out only directories and finally runs the wanted command for each one.

But what if not all directories were subversion working copies?

Filter based on directory contents

A subversion working copy is a directory with a hidden .svn folder inside.

PS C:\workspace> Get-ChildItem -force */* |
where {$_.name -eq ".svn"} |
foreach {svn update $_.parent}

This lists all children one level down (-force is to include hidden stuff), filters out only those named .svn and then runs the update on its parent folder.

If we needed to look for a file instead (which doesn’t have a parent property) we could do something like this:

PS C:\workspace> Get-ChildItem */* |
where {$_.name -eq "pom.xml"} |
foreach { cd $_.DirectoryName; mvn clean compile; cd ..}

Here we do basically the same thing except that we use the DirectoryName property instead of parent. We also actually go into each directory to run the command there rather than just passing the path to a command like in the svn example.

Gotta say, PowerShell is kind of neat 🙂