LordShaithis
LordShaithis

Reputation: 3

Powershell - Variable amount of Drives

So, I am going to throw this out. I am trying to write a simple health check for a bunch of systems. I know there are products that do it and whatnot. This is a special isolated circumstance where unless the software has prior approval I cant even consider freeware options. I have cobbled together the following:

Clear-Host
$date = Get-Date -Format "yyyy-MM-dd"
$cpuTime = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
$availMem = (Get-Counter '\Memory\Available MBytes').CounterSamples.CookedValue / 1024
$totalRam =  (Get-WmiObject Win32_ComputerSystem).totalphysicalmemory / (1024 * 1024 * 1024)
$DiskUsageC = (Get-Counter '\LogicalDisk(C:)\% Free Space').CounterSamples.CookedValue


$env:computername + "`t`t" + $date + "`t`t CPU Usage: " + $cpuTime.ToString("#,0.0") + "%" + "`t`t Memory Usage: " + ($availMem / $totalRam *100).ToString("#,0.0") + '%' + "`t`t Hard Disk Usage: " + "   (C:) " + $DiskUsageC.ToString("#,0.0") + "%" | Out-GridView -Title 'System Health Check'

It is by no means perfect, or clean. I am an SA. Not a developer. Its cobbled together via tweaking other ppls code. My question is, is there a good way for rather than explicitly stating the drives in the code, I can set a variable and it adapts to the amount of drives and gives me their usage percentage? These are servers with different numbers of drives. Can anyone offer suggestions or point me in the right direction?

Thanks for any help in advance!

Upvotes: 0

Views: 99

Answers (2)

AdminOfThings
AdminOfThings

Reputation: 25001

You can stick with your current format and just iterate through the logical drives/volumes:

$date = Get-Date -Format "yyyy-MM-dd"
$cpuTime = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue
$availMem = (Get-Counter '\Memory\Available MBytes').CounterSamples.CookedValue / 1024
$totalRam =  (Get-CimInstance Win32_ComputerSystem).totalphysicalmemory / (1024 * 1024 * 1024)

# List volumes if they have drive letters and are fixed (you can change this filter)
$drives = Get-Volume | Where {$_.DriveLetter -and $_.DriveType -eq 'Fixed'}
# Loop through each volume to create your formatted string
# $driveData is an array of those formatted strings.
$driveData = $drives | Foreach-Object {
     $letter = $_.DriveLetter
     "({0}:) {1}%" -f $letter,(Get-Counter "\LogicalDisk($($letter):)\% Free Space").CounterSamples.CookedValue.ToString('#,0.0')
}

$env:computername + "`t`t" + $date + "`t`t CPU Usage: " + $cpuTime.ToString("#,0.0") + "%" + "`t`t Memory Usage: " + ($availMem / $totalRam *100).ToString("#,0.0") + '%' + "`t`t Hard Disk Usage: $($driveData -join ', ')" |
    Out-GridView -Title 'System Health Check'

Explanation:

There are some notable techniques used here to achieve the desired results. $() is the sub-expression operator, which allows an expression to be evaluated within a string (code inside of double quotes). For example, "$($letter):" allows $letter to be substituted with its value and then have a : appended to that value.

$($driveData -join ', ') also occurs within double quotes (inside of an expandable string). This allows the elements of the array, $driveData, to be joined into a single string. Then each of those elements are separated by , (comma and space).

Upvotes: 0

ArcSet
ArcSet

Reputation: 6860

So lets talk POWERSHELL.

In Powershell we love to Pipe |. This means joining commands together to get the data we want. Once a command is done it will Pipe | the response to the next command. There is a Magic variable used that represents that passed response which is $_.

In this case looks like you want to build a type of sensor.

So lets solve the issue

There is a command called Get-PSDrive it basically allows you to interact with with OS environment.

If you run Get-PSDrive you will get stuff like

Name           Used (GB)     Free (GB) Provider      Root                                                                                                                                                         CurrentLocation
----           ---------     --------- --------      ----                                                                                                                                                         ---------------
Alias                                  Alias                                                                                                                                                                                     
C                 101.05        314.08 FileSystem    C:\                                                                                                 Users\Andrew Davis\Documents\Scripts\Powershell\Autoload\ActiveDirectory
Cert                                   Certificate   \                                                                                                                                                                           
D                  79.95        576.85 FileSystem    D:\ 

What we are looking for is the Provider and the Provider we want is FileSystem.

So lets pipe

Get-PSDrive -PSProvider 'FileSystem' | Foreach-Object{
    "Drive: $($_.Name), Free Space : $([math]::Round($_.Free / 1GB, 1)) GB"  
}

Will return something like

Drive: C, Free Space : 314.1 GB
Drive: D, Free Space : 576.8 GB
Drive: E, Free Space : 0.8 GB
Drive: F, Free Space : 6.2 GB
Drive: G, Free Space : 73.3 GB
Drive: H, Free Space : 29 GB
Drive: I, Free Space : 6.6 GB
Drive: J, Free Space : 24 GB

Upvotes: 1

Related Questions