Tuesday, 19 September 2017

Get-CimInstance PowerShell cmdlet doesn't have any methods

If you've moved from the Get-WmiObject to the new Get-CimInstance cmdlets you may find that these no longer have the methods available that you would have had when using Get-WmiObject.

This is because everything is being routed correctly though the WS-MAN protocol and the objects that are returned are not code and cannot be executed.

It's a simple work around - just pipe the object back to the Invoke-CimMethod cmdlet...

$printers = Get-CimInstance Win32_Printer
$descriptor = $printers[0] | Invoke-CimMethod -MethodName GetSecurityDescriptor

Monday, 18 September 2017

Get-Printer StartTime and UntilTime

The Windows PowerShell Get-Printer cmdlet provides a start and finish time for printer availability but confusingly this value is returned as an integer value.

More confusingly this is stored as a value of minutes from midnight GMT so if you print server is in GMT -5 and has a available from time of midnight you'll see the StartTime of 300.

If you'd like to convert the time to a DateTime that is more understandable that reflects what is seen in the UI try the following

$baseTime = [System.DateTime]::MinValue.AddDays(1)
$baseTime = $baseTime.AddHours([System.TimeZoneInfo]::Local.BaseUtcOffset.TotalHours)
$baseTime = $baseTime.AddMinutes(150)

Thursday, 24 August 2017

The PowerShell cmdlet Get-NetRoute returns more results than the standard "route print" command

We've been working to migrate our server documentation tool from a combination of WMI, and low level APIs to PowerShell and have come across an interesting issue.

Microsoft recommend using the PowerShell cmdlet Get-NetRoute as a replacement for the old "route print" command, but it returns more results than the standard "route print" command and the WMI class Win32_IP4RouteTable.

It turns out that the former returns routes for interfaces that are down whereas the later two methods do not. This is what leads to the inconsistency.

To ignore the results from network adapters that aren't up you need to correlate them with the results from the Get-NetAdapter cmdlet and check the ifOperStatus.

$routes = Get-NetRoute
$adapters = Get-NetAdapter
foreach ($route in $routes)
    $interfaceOnline = $true
    foreach ($adapter in $adapters)
        if ($adapter.InterfaceIndex -eq $route.InterfaceIndex)
            if ([System.Convert]::ToInt32($adapter.ifOperStatus) -ne 1) { $interfaceOnline = $false; }
    if (!$interfaceOnline) { continue; }