Querying WMI with a Timeout
This is thanks to my coworker Keith Munson, who is at least as passionate and adept at PSH as I am:
function Get-WmiObjectWithTimeout { <# Credit to Keith Munson for this. #> param( [string]$Class, [string]$ComputerName = $env:COMPUTERNAME, [string]$NameSpace = 'root\cimv2', [System.Management.ConnectionOptions]$ConnectionOptions = $null, [System.Management.EnumerationOptions]$EnumerationOptions = $null, [int]$Timeout = 15 )
if (!$Class) { $message = "$($MyInvocation.MyCommand.Name) -Class not specified, required."; Write-Error -ErrorAction SilentlyContinue -Message $message. Write-Warning -Message $message; return; break __outOfScript;
} # if (!$Class)
(!$ConnectionOptions) -and ($ConnectionOptions = New-Object System.Management.ConnectionOptions) | Out-Null; (!$EnumerationOptions) -and ($EnumerationOptions = New-Object System.Management.EnumerationOptions) | Out-Null; $EnumerationOptions.Set_Timeout((New-TimeSpan -Seconds $Timeout)); $scope = New-Object System.Management.ManagementScope "\\$ComputerName\$NameSpace", $ConnectionOptions; $scope.Connect(); $queryString = "SELECT * FROM $class"; $query = New-Object System.Management.ObjectQuery $queryString; $searcher = New-Object System.Management.ManagementObjectSearcher; $searcher.Set_options($EnumerationOptions); $searcher.Query = $queryString; $searcher.Scope = $Scope; try { $result = $searcher.Get();
} # try catch { $message = "$($MyInvocation.Line) returns {0}" -f $_.Exception.Message; Write-Error -ErrorAction SilentlyContinue -Message $message; Write-Warning -Message $message; } # catch
if ($result) { if ($result.Count) { $result;
} # if ($result.Count) else { $local:ErrorActionPreference = 'SilentlyContinue'; $Error.Clear(); $result; $message = "$($MyInvocation.Line) returns {0}" -f $Error[0].Exception.Message; Write-Error -ErrorAction SilentlyContinue -Message $message; Write-Warning -Message $message;
} # if ($result.Count) ... else
} # if ($result) } # function Get-WmiObjectWithTimeout |