Looking for powershell script to show freespace below 5% on drives - powershell

I made this script to display the values of disk spaces of multiple remote computers, but i need to add a filter to display only drives that are below 2% disks-space and to add the machine name to the table
Get-WmiObject Win32_LogicalDisk -ComputerName computer1, computer2, computer3 -Filter DriveType=3 | Select-Object DeviceID, #{'Name'='Size (GB)'; 'Expression'={[string]::Format('{0:N0}',[math]::truncate($_.size / 1GB))}}, #{'Name'='Freespace (GB)'; 'Expression'={[string]::Format('{0:N0}',[math]::truncate($_.freespace / 1GB))}}

I'd suggest using the newer Get-CimInstance cmdlet instead of Get-WmiObject.
You can add a Where-Object clause to filter on the percentage available and add the computername like this:
Get-CimInstance win32_LogicalDisk -ComputerName computer1, computer2, computer3 -Filter 'DriveType=3' |
Where-Object { (($_.FreeSpace / $_.Size) * 100) -lt 2 } |
Select-Object SystemName, Caption,
#{Name ='Size (GB)'; Expression = {[string]::Format('{0:N0}',[math]::Truncate($_.Size / 1GB))}},
#{Name ='Freespace (GB)'; Expression = {[string]::Format('{0:N0}',[math]::Truncate($_.FreeSpace / 1GB))}},
#{Name ='pct used'; Expression = {"{0:N2}" -f (($_.FreeSpace / $_.Size) * 100)}} |
Format-Table -AutoSize
The questions title says to filter on 5%, but the question text talks about 2% diskspace available

Related

Formatting multiple result sets together in powershell

Get-WmiObject -Class Win32_OperatingSystem -ComputerName (Get-Content "C:\Temp\Servers.txt") | SELECT-Object PSComputerName, #{Name="Memory (RAM in GB)";Expression={[Math]::Round($_.TotalVisibleMemorySize/1024/1024)}} | Format-Table
Get-WmiObject -Class Win32_logicaldisk -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object PSComputerName, DriveType, DeviceID, VolumeName, #{Name="Size";Expression={[math]::ceiling($_.Size /1GB)}} , #{Name="FreeSpace";Expression={[math]::ceiling($_.FreeSpace /1GB)}}, Compressed | where DriveType -eq 3 | Format-Table
Get-WmiObject -Class Win32_OperatingSystem -ComputerName (Get-Content "C:\Temp\Servers.txt")| Select-Object PSComputerName, BuildNumber, BuildType, Caption, CodeSet, OSArchitecture, SystemDrive, TotalVisibleMemorySize, Version | Format-Table
Get-WmiObject -Class win32_product -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object Name, Version, Vendor, InstallDate | Format-Table
Get-WmiObject -Class Win32_Service -ComputerName (Get-Content "C:\Temp\Servers.txt") | Select-Object PSComputerName, DisplayName, StartName, PathName, StartMode| where DisplayName -Like "*xyz*" |Format-Table
I have till now managed to piece together the above to get the information I need from serveral servers, however now I want to format it so that I can collate information for each server in a format that I can display
for eg.
Server : ABC
RAM : 64 GB
Number of Processors : 8
Disk :
Table of disk Sizes Etc
Any pointers would be appreciated
With all these properties, you would get a nested object array, which probably is easiest to view in JSON format.
I have changed all Get-WmiObject into the newer and faster Get-CimInstance cmdlets below
$result = Get-Content "C:\Temp\Servers.txt" | ForEach-Object {
# create an ordered hashtable to store the results for each server
$pcinfo = [ordered]#{}
# System info
$data = Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName $_
$pcinfo['Computer'] = $data.PSComputerName
$pcinfo['Memory (RAM in GB)'] = '{0:N2}' -f ($data.TotalPhysicalMemory / 1GB)
# OS info
$data = Get-CimInstance -ClassName Win32_OperatingSystem -ComputerName $_
$pcinfo['BuildNumber'] = $data.BuildNumber
$pcinfo['BuildType'] = $data.BuildType
$pcinfo['Caption'] = $data.Caption
$pcinfo['CodeSet'] = $data.CodeSet
$pcinfo['OSArchitecture'] = $data.OSArchitecture
$pcinfo['SystemDrive'] = $data.SystemDrive
$pcinfo['TotalVisibleMemorySize'] = $data.TotalVisibleMemorySize
$pcinfo['Version'] = $data.Version
# Product info (array of objects)
$pcinfo['Products'] = Get-CimInstance -ClassName Win32_Product -ComputerName $_ |
Select-Object Name, Version, Vendor, InstallDate
# Local fixed disk info (array of objects)
$pcinfo['FixedDrives'] = Get-CimInstance -ClassName Win32_LogicalDisk -ComputerName $_ -Filter 'DriveType=3' |
Sort-Object DeviceID |
Select-Object DriveType, DeviceID, VolumeName,
#{Name="Size";Expression={"{0:N2} GB" -f ($_.Size / 1GB)}},
#{Name="FreeSpace";Expression={"{0:N2} GB" -f ($_.FreeSpace / 1GB)}},
Compressed
# Services info (array of objects)
$pcinfo['Services'] = Get-CimInstance -ClassName Win32_Service -ComputerName $_ |
Where-Object { $_.DisplayName -like '*Adobe*' } |
Select-Object DisplayName, StartName, PathName, StartMode
# convert the hashtable to PSObject and output
[PsCustomObject]$pcinfo
}
# output the whole structure as JSON for easier reading and optionally save it to file
$result | ConvertTo-Json -Depth 3 # | Set-Content -Path 'Path\To\Output.json' -Force

powershell - remote disk information unique description

Need some assistance with the below script created, i can create a HTML report of the disk space for all remote machines i specified; however how do i add a meaningful description for each host i.e the pic below.
Script below
$Machine = #("Fakehost1", "Fakehost2", "fakehost3")
Get-CimInstance Win32_LogicalDisk -ComputerName $Machine -Filter "DriveType = '3'" -ErrorAction SilentlyContinue |
Select-Object PsComputerName, DeviceID,
#{N="Disk Size (GB) "; e={[math]::Round($($_.Size) / 1073741824,0)}},
#{N="Free Space (GB)"; e={[math]::Round($($_.FreeSpace) / 1073741824,0)}},
#{N="Free Space (%)"; e={[math]::Round($($_.FreeSpace) / $_.Size * 100,1)}} |
Sort-Object -Property 'Free Space (%)' |
ConvertTo-Html -Head $Head -Title "$Title" -PreContent "<p><font size=`"6`">$Title</font><p>Generated on $date</font></p>" > $HTML
A quick fix is to Sruce up the PSComputerName object in the same Select-Object command. You're already doing a lot of calculated properties what's 1 more...
Get-CimInstance Win32_LogicalDisk -ComputerName $Machine -Filter "DriveType = '3'" -ErrorAction SilentlyContinue |
Select-Object #{N = 'PSComputerName'; E = { $_.PSComputerName + " : Description" }},
DeviceID,
#{N="Disk Size (GB) ";e={[math]::Round($($_.Size) / 1073741824,0)}},
#{N="Free Space (GB)";e={[math]::Round($($_.FreeSpace) / 1073741824,0)}},
#{N="Free Space (%)";e={[math]::Round($($_.FreeSpace) / $_.Size * 100,1)}} |
Sort-Object -Property 'Free Space (%)' |
ConvertTo-Html -Head $Head -Title "$Title" -PreContent "<p><font size=`"6`">$Title</font><p>Generated on $date</font></p>" > $HTML
This tested good in my environment, but you will have to decide how to or what the actual description should be... If you are in an AD environment maybe you can create a hash to hold the descriptions like:
$Descriptions = #{}
$Machine |
Get-ADComputer -Properties Description |
ForEach-Object{ $Descriptions.Add( $_.Name, $_.Description ) }
Then change the PSComputerName expression like:
#{N = 'PSComputerName'; E = { $_.PSComputerName + $Descriptions[$_.PSComputerName] }}
This would reference the hash and return the value you got from the AD description attribute. Of course, that means the attribute has to be populated. But it's just 1 idea to demonstrate the point that the description must be mined from somewhere.
Update:
To answer your comment, You could manually specify the hash instead. use something like below, before the Get-CimInstance command. Make sure to remove the previous AD stuff...
$Descriptions =
#{
Fakehost1 = "SQL Server for some bug app..."
Fakehost2 = "File Server 1"
Fakehost3 = "Another file server"
}

Format results from a Get-WmiObject script to match list from get-content .txt file

I am trying to write a script that will get drive current drive space on our servers and return them to an output file.
Here is the script as of now:
$ServerName = Get-Content -Path "C:\Users\*****\Desktop\Testing Files\serverlist.txt"
Get-WmiObject Win32_LogicalDisk -ComputerName $ServerName -Filter DriveType=3 | Select-Object DeviceID, #{'Name'='Size (GB)'; 'Expression'={Expression'={[string]::Format('{0:NO}',[math]::truncate($_.size / 1GB))}}, #{'Name'='Freespace (GB)'; 'Expression'={[string]::Format('{0:NO}',[math]::truncate($_.freespace / 1GB))}}
Out-file "C:\users\xxxxxx\desktop\testing files\server space results.txt"
will not write to a text file; only displays results
The results display device ID, size (GB), freespace (GB) with no issues except one. Every drive is listed as C: and E: but does not split them up based on the device name so it is hard to tell which results go to which server. Below is a sample of the results of the script:
DeviceID Size (GB) Freespace (GB)
-------- --------- --------------
C: 58 13
E: 499 499
C: 79 30
E: 799 103
Any ideas?
You've got a few typos and/or syntax errors. Also if you want the Computer Name PowerShell adds the PSComputerName property:
$ServerName = Get-Content -Path "C:\Users\*****\Desktop\Testing Files\serverlist.txt"
Get-WmiObject Win32_LogicalDisk -ComputerName $ServerName -Filter DriveType=3 |
Select-Object PSComputerName,DeviceID,
#{'Name'='Size (GB)'; Expression = {[string]::Format('{0:N0}',[math]::truncate($_.size / 1GB))}},
#{'Name'='Freespace (GB)'; Expression = {[string]::Format('{0:N0}',[math]::truncate($_.freespace / 1GB))}} |
Out-file "C:\users\xxxxxx\desktop\testing files\server space results.txt"
Note: I prefer to use win32_Volume instead. Also you should think about using Get-CimInstance instead of Get-WMIObject. The latter is deprecated.
Update
Here's a slightly modified version. I typically use [Math]::Round() in these cases. It will keep the value numeric so it aligns right.
$ServerName = Get-Content -Path "C:\Users\*****\Desktop\Testing Files\serverlist.txt"
Get-WmiObject Win32_LogicalDisk -ComputerName $ServerName -Filter DriveType=3 |
Select-Object PSComputerName,DeviceID,
#{'Name'='Size (GB)'; Expression = { [Math]::Round( ($_.size / 1GB), 0 ) } },
#{'Name'='Freespace (GB)'; Expression = { [Math]::Round( ($_.freespace / 1GB), 0 ) } } |
Out-file "C:\temp\xxxxxx\desktop\testing files\server space results.txt"

How to get output in GB instead of B

I found a script to check the available space on a remote computer. However I can't find how I can get the output in GB instead of B.
I don't know a lot about Powershell. Can somebody help me adjusting this code so I can see the available free disk space on a remote computer
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName STR3598C -Filter "DeviceID='C:'" | Select-Object Size,FreeSpace
$disk.Size
$disk.FreeSpace
A possible way to achieve this could be to use the following:
gwmi win32_logicaldisk -ComputerName STR3598C -Filter "DeviceID='C:'" | Format-Table DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1GB,2)}},#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
Expected output:
DeviceId MediaType Size FreeSpace
-------- --------- ---- ---------
C: 12 215.52 111.1
Another way is to store the results in a variable (like with your code example) and format that for output to screen and/or save it in a CSV file:
$computer = 'STR3598C'
$disk = Get-WmiObject Win32_LogicalDisk -ComputerName $computer -Filter "DeviceID='C:'" |
Select-Object #{Name = 'Computer'; Expression = {$_.PSComputerName}},
DeviceID, VolumeName,
#{Name = 'Size'; Expression = {'{0:N2}' -f ($_.Size / 1GB)}},
#{Name = 'FreeSpace'; Expression = {'{0:N2} GB' -f ($_.FreeSpace / 1GB)}}
# output on screen
$disk | Format-Table -AutoSize
# or save the output as CVS
$disk | Export-Csv -Path 'D:\disksize.csv' -NoTypeInformation
Output on screen
Computer DeviceID VolumeName Size FreeSpace
-------- -------- ---------- ---- ---------
STR3598C C: Systeem 232,79 GB 89,33 GB

How to imbricate a command inside another command?

I have the following PowerShell script which allows me to collect information about disks & volumes on Windows servers of the domain where the script is launched:
$ErrorActionPreference = 'SilentlyContinue'
Get-ADComputer -Filter 'OperatingSystem -like "*Server*"' -Properties * |
Select-Object Name |
ForEach-Object {
if (Test-Connection $_.Name -Count 1) {
Get-WmiObject -Class Win32_LogicalDisk -ComputerName $_.Name -Filter "DriveType=3" |
Select-Object PSComputerName, DeviceID,
#{Name="Size /GB";Expression={[math]::Round($($_.Size / 1GB), 2)}},
#{Name="Free /GB";Expression={[math]::Round($($_.Freespace / 1GB), 2)}},
#{Name="Free %";Expression={[math]::Round($($_.Freespace/$_.Size)*100, 1)}}
} else {
Write-Nost $_.Name " Connection Error"
}
} |
sort PSComputerName |
Format-Table -AutoSize
I get the following result:
SRV01 Connection Error
SRV02 Connection Error
PSComputerName DeviceID Size /GB Free /GB Free %
-------------- -------- ------------ --------- -------
SERVER03 C: 125,51 105,59 84,1
SERVER04 C: 24,83 7,38 29,7
SERVER05 E: 14,65 7,36 50,2
SERVER06 C: 49,66 29,28 59
I want to add an additional column with the OS for each server.
I would like this column to be in second position, after the "PSComputerName" column. How can I get this result?
I think I use a nested command by adding a Get-WmiObject Win32_OperatingSystem | Select-Object caption in the Get-WmiObject -Class Win32_LogicalDisk ..., but I don't know which syntax to use and how to imbricate a command in another command.
Don't use -properties *... it's going to retrieve every single populated property which you don't need in this script.
Get-ADComputer has an operatingsystem property.
Not tested:
Get-ADComputer -Filter 'OperatingSystem -like "*Server*"' -Properties OperatingSystem | ForEach-Object {
$OS = $_.OperatingSystem
If (Test-Connection $_.Name -Count 1 -Quiet){
Get-WmiObject -Class win32_logicalDisk -ComputerName $_.Name -Filter "DriveType=3" |
Select-Object pscomputername, #{Name="OS";Expression={$OS}} ,DeviceID,
#{Name="Size /GB";Expression={[math]::Round($($_.size / 1GB), 2)}},
#{Name="Free /GB";Expression={[math]::Round($($_.freespace / 1GB), 2)}},
#{Name="Free %";Expression={[math]::Round($($_.Freespace/$_.Size)*100, 1)}}
}
else {
Write-host $_.Name " Connection Error"
}
} | sort pscomputername | Format-Table -AutoSize