Chapters/scripting-at-scale/getdiskspace.ps1


Function Get-DiskSpace {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory)]
[string[]]$Computername
)

Invoke-Command -scriptblock {
Get-CimInstance -ClassName win32_logicaldisk -filter "deviceid='c:'" |
Select @{Name="Computername";Expression={$_.SystemName}},DeviceID,Size,Freespace,
@{Name="PctFree";Expression={ "{0:p2}" -f $($_.freespace/$_.size)}}
} -ComputerName $computername -HideComputerName  | 
Select * -ExcludeProperty RunspaceID
}

#with error handling
Function Get-DiskSpace {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory)]
[string[]]$Computername
)

foreach ($computer in $computername) {
    Write-Verbose "Querying $computer"
    Try {
        Invoke-Command -scriptblock {
        Get-CimInstance -ClassName win32_logicaldisk -filter "deviceid='c:'" |
        Select @{Name="Computername";Expression={$_.SystemName}},DeviceID,Size,Freespace,
        @{Name="PctFree";Expression={ "{0:p2}" -f $($_.freespace/$_.size)}}
        } -ComputerName $computer -HideComputerName -ErrorAction stop  | 
        Select * -ExcludeProperty RunspaceID
    }
    Catch {
        Write-Warning "[$($computer.toupper())] $($_.exception.message)"
    }
} #foreach

}

#from the pipeline
Function Get-DiskSpace {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory, ValueFromPipeline)]
[string[]]$Computername
)

Begin {
    #initialize an array
    $computers=@()
}

Process {
    #add each computer to the array
    $computers+=$Computername
}

End {
    #run the actual command here for all computers
    Invoke-Command -scriptblock {
     Get-CimInstance -ClassName win32_logicaldisk -filter "deviceid='c:'" |
     Select @{Name="Computername";Expression={$_.SystemName}},
     DeviceID,Size,Freespace,
     @{Name="PctFree";Expression={ "{0:p2}" -f $($_.freespace/$_.size)}}
    } -ComputerName $computers -HideComputerName  | 
    Select * -ExcludeProperty RunspaceID
}
}

#with jobs
Function Get-DiskSpace {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory, ValueFromPipeline)]
[string[]]$Computername,
[switch]$AsJob
)

Begin {
    #initialize an array
    $computers=@()
}

Process {
    #add each computer to the array
    $computers+=$Computername
}

End {
    #add a parameter
    $psboundParameters.Add("HideComputername",$True)

    #run the actual command here for all computers
    Invoke-Command -scriptblock {
     Get-CimInstance -ClassName win32_logicaldisk -filter "deviceid='c:'" |
     Select @{Name="Computername";Expression={$_.SystemName}},
     DeviceID,Size,Freespace,
     @{Name="PctFree";Expression={ "{0:p2}" -f $($_.freespace/$_.size)}}
    } @psboundParameters  | 
    Select * -ExcludeProperty RunspaceID
}
}

#using runspaces
Function Get-DiskSpace {
[cmdletbinding()]
Param(
[Parameter(Position = 0, Mandatory)]
[string[]]$Computername
)

$rspace = @()

foreach ($computer in $computername) {
Write-Verbose "Creating runspace for $Computer"
    $run = [powershell]::Create()
    $run.AddCommand("get-ciminstance").addparameter("computername",$computer) | Out-Null
    $run.Commands[0].AddParameter("classname","win32_logicaldisk") | Out-Null
    $run.commands[0].addParameter("filter","deviceid='c:'") | Out-Null
    $handle = $run.beginInvoke()
    #add the handle as a property to make it easier to reference later
    $run | Add-member -MemberType NoteProperty -Name Handle -Value $handle
    $rspace+=$run
} #foreach

#wait for everything to complete
While (-Not $rspace.handle.isCompleted) {
    #an empty loop waiting for everything to complete
}

#get results
$results=@()
for ($i = 0;$i -lt $rspace.count;$i++) {
    #stop each runspace
    $results+= $rspace[$i].EndInvoke($rspace[$i].handle)
}

#cleanup
$rspace.ForEach({$_.dispose()})

#process the results
$Results | Select @{Name="Computername";Expression={$_.SystemName}},
DeviceID,Size,Freespace,
@{Name="PctFree";Expression={ "{0:p2}" -f $($_.freespace/$_.size)}}

}