Do you have any way of getting server name from the attached list of IPs?

Every now and then I get a simple script idea in my email, like this one from a couple weeks ago:

Do you have any way of getting server name from the attached list of IPs?

This is a pretty simple request, and there are probably thousands of possible solutions, but I threw together a quick function that accepts an IP Address as a string and returns the IP address and a host name… like this:
[cc lang=”powershell”]
Function Get-HostName ([string]$ipAddress) {
New-Object psobject -Property @{
IPAddress = $ipAddress
HostName = try { [system.net.dns]::GetHostByAddress($ipAddress).HostName } catch { “UNKNOWN” }
}
}
[/cc]

That’s almost a solution… the only thing remaining would be to read in the text file, call the function for each line and then export the results. That can all be done in one line of code, but I put in some line breaks to make it easier to read:
[cc lang=”powershell”]
Get-Content ipList.txt |
%{ Get-HostName $_ } |
Export-Csv MyIPsExport.csv -NoTypeInformation
[/cc]

Posted in Scripting | 1 Comment

When are Windows patches happening?

As most people know, Microsoft releases patches on the second Tuesday of the month. In some organizations these patches are deployed to development, test and QA systems within a couple of days of the release. However, production systems can’t be patched until the next maintenance window. Assuming this patch window is on a Saturday, we need to find the first Saturday after the second Tuesday. When looking at a calendar this is pretty simple for most people to figure out. However, when you need a whole years worth it takes a few minutes to calculate. What we need is some code to look these up for us…like this function:

[cc lang=”Powershell”]
Function Get-WsusSaturday {
param([datetime]$date=(Get-Date) )
$numberOfTuesdays=0

1..([datetime]::DaysInMonth( $date.year , $date.month )) | %{
$thisDate = Get-Date “$($date.month)/$($_)/$($date.year)”
if ([string]$thisDate.DayOfWeek -eq ‘Tuesday’) {
$numberOfTuesdays++
if ($numberOfTuesdays -eq 2) {
$thisDate.AddDays(4).ToLongDateString()
}
}
}
}
[/cc]
Line 2: accept the date as a parameter and cast it to a date/time value, defaulting to today’s date if nothing is provided
Line 3: max sure we don’t think its Tuesday already
Line 5: starting on the first of each month, loop through the max number of days in the month
Line 8: if the date is Tuesday, add one to the counter
Line 9: once we find the second Tuesday
Line 10: add 4 more days to find the following Saturday and return the date text

You can take this function and do something creative, like find the next 5 years worth of patch Saturdays.
[cc lang=”powershell”]
13..18 | %{
$year = $_
1..12 | %{ Get-WsusSaturday “$_/1/$year” }
}
[/cc]

Posted in Scripting | Leave a comment

Hashtables: Item has already been added

In my previous two posts about hashtables I provided examples for creating a hashtable, returning a specific value and a description around performance. This post will focus on the errors you should expect if you start using a hashtable.

The most common exception I see happens when the data I’m storing in the hashtable is not unique. For example, in the first post in the series we created a simple hashtable from a list of HTML colors. If my input list had the color ‘red’ listed on two different lines, I would have seen an error similar to this:

Add : Exception calling “Add” with “2” argument(s): “Item has already been added. Key in dictionary: ‘Red’ Key being
added: ‘Red'”
At line:1 char:17
+ $colorCodeHT.Add <<<< ('Red','123456') + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException

This is an easy error message to generate if you want to see the actual error. Follow the examples in the first post and then try and re-add the color red using the following line:
[cc lang=”powershell”]
$colorCodeHT.Add(‘Red’,’123456′)
[/cc]

The hashtable object includes a .Contains method, which can be used in an if statement to prevent this exception from happening:
[cc lang=”powershell”]if ($colorCodeHT.Contains(‘Red’)) { “Color ‘red’ has already been added” } else { $colorCodeHT.Add(‘Red’,’123456′) }[/cc]

This statement checks for the presence of a ‘Red’ item and only attempts to add if a value does not already exist.

Posted in Scripting | Leave a comment

Hashtables: Adding, Updating and Removing Items

To help describe these concepts, I have listed a few examples based on a CSV file containing HTML color codes.

For purposes of sample data, create an array object of colors and HTML color codes.
[cc lang=”powershell”]$colorCodes = Import-Csv ColorCodes.csv[/cc]

Define a hashtable object:
[cc lang=”powershell”]$colorCodeHT = @{}[/cc]

Examples for adding to a hashtable:
[cc lang=”powershell”]
# For the old vbscripter (this is the method I use)
# $colorCodeHT.Add(‘key’,’value’)
$colorCodes | %{$colorCodeHT.Add($_.ColorName, $_.Code)}

# For the person who likes equal signs
# $colorCodeHT[‘key’] = ‘Value’
$colorCodes | %{$colorCodeHT[$_.ColorName] = $_.Code}
[/cc]

Examples for updating existing entries
[cc lang=”powershell”]
# Using square brackets, just like the above ‘add’ example
$colorCodeHT[‘Red’] = ‘#123456’
[/cc]

Examples for removing from a hashtable:
[cc lang=”Powershell”]
# Remove a single item by key
$colorCodeHT.Remove(‘Red’)

# Remove all of the entries from the hashtable:
$colorCodeHT.Clear()
[/cc]

Posted in Scripting | Leave a comment

Hashtables: Performance

In the previous post I provided a quick introduction to creating and using a hashtable object. If you are paying attention, you might have asked “Why would I go to extra work to create a hashtable when I can make the original object work?” The answer is performance…but lets expand on this answer.

We can use Measure-Command to show how long each of these statements takes to execute. Here is a quick refresher on using Measure-Command to show how long it takes to execute a command…just replace “PUT EACH COMMAND HERE” with your actual command:
[cc lang=”Powershell”]
(Measure-Command { “PUT EACH COMMAND HERE” }).TotalMilliseconds
[/cc]

Using the examples from the previous post, we return Total Millisecond execution times of:

Example Execution Time (ms)
2: Select item from array object 19.0030
3: Create a hashtable from array object 19.2045
4: Select item from hashtable 0.0311

In this sample, returning a value from the hashtable (example 4) is 600 times faster than using the array object (example 2)! Just because this step was faster, it doesn’t mean hashtables are always best. If we take into account the overhead from creating the hashtable (add the execution times of example 3 and 4 together), then using the array object is actually more efficient. The performance gain is only noticeable if you plan to re-use the hashtable over several iterations.

[cc lang=”Powershell”]
# Example 5: Selecting multiple times from array object
(Measure-Command {
($colorCodes | Where-Object {$_.ColorName -eq ‘Red’}).Code
($colorCodes | Where-Object {$_.ColorName -eq ‘Blue’}).Code
($colorCodes | Where-Object {$_.ColorName -eq ‘Green’}).Code
($colorCodes | Where-Object {$_.ColorName -eq ‘Black’}).Code
}).TotalMilliseconds

# Example 6: Creating hashtable and selecting from it multiple times
(Measure-Command {
$colorCodeHT = @{}
$colorCodes | %{ $colorCodeHT.Add($_.ColorName, $_.Code) }
$colorCodeHT[‘Red’]
$colorCodeHT[‘Blue’]
$colorCodeHT[‘Green’]
$colorCodeHT[‘Black’]
}).TotalMilliseconds
[/cc]

Example Execution Time (ms)
5: Select from array object multiple times 57.7053
6: Create hashtable and select from it multiple times 17.8322

Even though a hashtable requires a bit of setup, it becomes more efficient with repetitive use. The example with HTML color codes only has around 290 items in the hashtable. This performance improvement is more noticeable with larger hashtables, especially when they are used many times within the script.

Posted in Scripting | Leave a comment