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