2

I am trying to retrieve logical disk information from remote machines using Daniele's custom get-wmiobject function due to my need for a timeout parameter.

The function works perfectly fine, but I also want to store the $results in a variable and loop through it to find drives whose free space has dropped below a certain threshold.

Here is my portion of the code. I added a $where parameter to Daniele's function to be attached to the query. His function is otherwise the same.

Function get-wmicustom([string]$computername,[string]$namespace,[string]$class,[int]$timeout=15,[string]$where)
{
    $ConnectionOptions = new-object System.Management.ConnectionOptions
    $EnumerationOptions = new-object System.Management.EnumerationOptions

    $timeoutseconds = new-timespan -seconds $timeout
    $EnumerationOptions.set_timeout($timeoutseconds)

    $assembledpath = "\\" + $computername + "\" + $namespace
    write-host $assembledpath -foregroundcolor green

    $Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions
    $Scope.Connect()

    $querystring = "SELECT * FROM " + $class + " " + $where
    write-host $querystring

    $query = new-object System.Management.ObjectQuery $querystring
    $searcher = new-object System.Management.ManagementObjectSearcher
    $searcher.set_options($EnumerationOptions)
    $searcher.Query = $querystring
    $searcher.Scope = $Scope

    trap { $_ } $result = $searcher.Get()

    return $result
}

$servers = get-content -Path "c:\ServerMonitoring\servers.txt"
$threshold = 5

foreach($server in $servers)
{
    write-host "Checking server $server..."

    #$drive_information = get-wmiobject -ComputerName $server -query "select Name, FreeSpace from Win32_logicaldisk where MediaType = 12"
    $drive_information = get-wmicustom -ComputerName $server -NameSpace "root\cimv2" -Class Win32_logicaldisk -TimeOut 3 -Where "WHERE MediaType = 12"

    write-host "Drive information collected from $server..."

    foreach($drive in $drive_information)
    {
        $drive_freespace_gb = [Math]::Round($drive.FreeSpace / 1024 / 1024 / 1024, 2)
        $drive_name = $drive.Name

        write-host "Checking drive $drive_name"

        if ($drive_freespace_gb -le $threshold -and $drive_name -notlike "*T:*")
        {
            write-host "Drive $drive_name on $server has only $drive_freespace_gb GB left."
            $wait = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
        }
    }
}

When I run this script from the command line, it gives this error:

The '=' operator failed: Invalid Class.

I understand that this might be due to the $results being returned here is a ManagementObjectCollection .Net object. So I tried converting this to a string by attaching the ToString() method to the Get() method. This stopped the error, but the ToString() method simply returns the name of the class the object belongs to, not the actual data. I've also tried Get().GetEnumerator().ToString() with a similar result.

How do I go about converting the results into a format readable by Powershell?

deutschZuid
  • 1,028
  • 2
  • 15
  • 33

1 Answers1

0

the syntax can be:

$SearchKBsResult | select <property you want> | foreach {$_.property you want}
dsaydon
  • 4,421
  • 6
  • 48
  • 52