Stop Powershell Script if disk size is less than X - powershell

I wonder if you could help me out guys.
I need to stop a powershell script if the disk size of partition E is less than 10GB, and to continue if it´s more than 10GB.
So far i managed to get my disk size listed with this.
Get-WmiObject -Class win32_logicaldisk | Format-Table DeviceId,#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}}
And i get this result:
DeviceId
Freespace
A
0
C
77.9
D
0
E
34.05
So, i want to stop the powershell script if E unit has less than 10GB.
How can i do it?
Thanks in advance

If you want to put the Freespace of E in a variable you can do this :
$VarSpace = $(Get-WmiObject -Class win32_logicaldisk | Where-Object -Property Name -eq C:).FreeSpace/1GB
then you can do a simple if for check :
if ($VarSpace -le 10){ <Something for stopping you script like exit> }

You can use the Get-Volume cmdlet for that or Get-CimInstancerather than the old Get-WmiObject:
$freeOnE = (Get-CimInstance -ClassName win32_logicaldisk | Where-Object {$_.DeviceID -eq 'E:'}).FreeSpace / 1GB
or
$freeOnE = (Get-Volume -DriveLetter E).SizeRemaining / 1GB
Then exit your PowerShell session if this value is below 10Gb
if ($freeOnE -lt 10) { exit }

Related

How to exclude part of an output in Powershell?

i am writing a script that accepts the device ID as an argument to check the used percentage of a disk. Here is my code.
$device_id = $args[0]
Get-WmiObject -Class Win32_LogicalDisk |
Select-Object -Property DeviceID,
#{label='UsedPercentage'; expression={[Math]::Round((($_.Size - $_.FreeSpace)/$_.Size) * 100, 2)}} |
findstr $device_id
Here is my output. i am passing an argument to see usage of the device by device ID.
PS D:\Development\Powershell> .\disk-usage.ps1 D:
D: 57.69
What i want to do is to just output that number. How do i do this?
There's no need to use findstr to filter the output. Instead, use the parameter argument to filter your WMI query:
$device_id = $args[0]
# use argument to filter WMI query
Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID = '$device_id'" |ForEach-Object {
# output the free space calculation, nothing else
[Math]::Round((($_.Size - $_.FreeSpace)/$_.Size) * 100, 2)
}
You can add the 'used percentage' as a property to the WMI object you get back from your query:
$deviceID = args[0]
$diskUsage = Get-WmiObject -Query "SELECT FreeSpace, Size FROM Win32_LogicalDisk WHERE DeviceID = '$deviceID'" |
Add-Member -MemberType ScriptProperty -Name 'UsedPercentage' -Value {[Math]::Round((($this.Size - $this.FreeSpace)/$this.Size) * 100, 2)} -PassThru
Now, $diskUsage is a WMI object with Size, FreeSpace and UsedPercentage properties (as well as some WMI metadata properties you can ignore). You can output the value of any of them by refering to the one you want:
$diskUsage.UsedPercentage
15.3
Or show them in a neat table:
$diskUsage | Format-Table Size, FreeSpace, UsedPercentage -AutoSize
Size FreeSpace UsedPercentage
---- --------- --------------
1013310287872 858247196672 15.3

Disk Space Check in Powershell

I am currently checking disk space size using power shell but was wondering how I can amend the below to add a percentage of space left?
Format-Table DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1MB,2)}},#{n="FreeSpace";e={[math]::Round($_.FreeSpace/1MB,2)}}
I have tried to do it by changing the math but no luck.
gwmi win32_logicaldisk -Computername PCNAME| Format-Table DeviceId, MediaType, #{n="Size";e={[math]::Round($_.Size/1MB,2)}},#{n="FreeSpace" (%);e={[math]::Round($_.FreeSpace/$_.Size*100,2)}}|Out-File c:\PMC\Disk\OutPut\Newcastle.txt
This just returns an error.
Here is an example how to do it:
gwmi Win32_LogicalDisk -Filter "DeviceID='C:'" | select Name, FileSystem,FreeSpace,BlockSize,Size | % {$_.BlockSize=(($_.FreeSpace)/($_.Size))*100;$_.FreeSpace=($_.FreeSpace/1GB);$_.Size=($_.Size/1GB);$_}| Format-Table Name, #{n='FS';e={$_.FileSystem}},#{n='Free, Gb';e={'{0:N2}'-f
$_.FreeSpace}}, #{n='Free,%';e={'{0:N2}'-f $_.BlockSize}} -AutoSize
output:
Name FS Free, Gb Free,%
---- -- -------- ------
C: NTFS 593.59 31.88
Here's part of a script I have written that may help you:
If (Test-Path 'C:')
{
$CDisk = GWMI Win32_LogicalDisk -Filter "DeviceID='C:'"
$CDisk = #{'Size' = [Math]::Round($CDisk.Size / 1GB);
'FreeSpace' = [Math]::Round($CDisk.FreeSpace / 1GB)}
$CDisk.Add('Usage', ($CDisk.Size - $CDisk.FreeSpace))
$CDisk.Add('PercentUsage', [Math]::Round(($CDisk.Usage / $CDisk.Size) * 100))
"C: drive free space: $($CDisk.FreeSpace)GB"
"C: drive capacity: $($CDisk.Size)GB"
'--------------------------------'
"Disk usage: $($CDisk.Usage)GB ($($CDisk.PercentUsage)%)"
}

Powershell free disk space for drives without drive letter

I am working on a power shell script based on http://www.powershellneedfulthings.com/?p=36 to check the disk space for volumes that do not have a driver letter assigned.
The script works pretty well, but I'd like to filter that only drives are shown that have less than 10% free disk space. I'm running into troubles using the where-object filter with hash tables.
# calculations for displaying disk size information
$TotalGB = #{Name="Capacity(GB)";expression={[math]::round(($_.Capacity/ 1GB),2)}}
$FreeGB = #{Name="FreeSpace(GB)";expression={[math]::round(($_.FreeSpace / 1GB),2)}}
$FreePerc = #{Name="Free(%)";expression={[math]::round(((($_.FreeSpace / 1GB)/($_.Capacity / 1073741824)) * 100),0)}}
# array declarations
$volumes = #()
# import server names to check
$servers = (Get-Content .\servers.txt)
# check disk space for volumes without drive letter
foreach ($server in $servers){
$volumes += Get-WmiObject -computer $server win32_volume | Where-Object {$_.DriveLetter -eq $null -and $_.Label -ne "System Reserved"}
}
$volumes | Select SystemName, Label, $TotalGB, $FreeGB, $FreePerc | Format-Table -AutoSize
What I tried is:
Where-Object {$FreePerc -le 10}
The current output is:
SystemName Label Capacity(GB) FreeSpace(GB) Free(%)
---------- ----- ------------ ------------- ----
SERVER01 X:\data\ 9.97 0.89 9
SERVER01 X:\log\ 9.97 1.20 12
SERVER01 X:\info\ 9.97 3.49 35
I'd like to only show the volumes that have less than 10% free disk space. So in this case, only the first entry should be shown.
Thanks!
I think the where clause variable $FreePerc is the issue. Arco had the right idea.
$volumes | Select SystemName, Label, $TotalGB, $FreeGB, $FreePerc | Where-Object {$_.'Free(%)' -le 10} | Format-Table -AutoSize
I put the property in single quotes because i think PowerShell would try to evaluate (%) otherwise. Also to make Arco's solution work it might just be easier to call the Name propery of $FreePerc. That way you only have to update one location
$volumes | Select SystemName, Label, $TotalGB, $FreeGB, $FreePerc | Where-Object {$_.($FreePerc.Name) -le 10} | Format-Table -AutoSize

Verifying system partition alignment via scripting

I'm trying to verify that the file system partitions within each of the servers I'm working on are aligned correctly. I've got the following script that when I've tried running will either claim that all virtual servers are aligned or not aligned based on which if statement I use (one is commented out):
$myArr = #()
$vms = get-vm | where {$_.PowerState -eq "PoweredOn" -and $_.Guest.OSFullName -match "Microsoft Windows*" } | sort name
foreach($vm in $vms){
$wmi = get-wmiobject -class "win32_DiskPartition" -namespace "root\CIMV2" -ComputerName $vm
foreach ($partition in $wmi){
$Details = "" | Select-Object VMName, Partition, Status
#if (($partition.startingoffset % 65536) -isnot [decimal]){
if ($partition.startingoffSet -eq "65536"){
$Details.VMName = $partition.SystemName
$Details.Partition = $partition.Name
$Details.Status = "Partition aligned"
}
else{
$Details.VMName = $partition.SystemName
$Details.Partition = $partition.Name
$Details.Status = "Partition not aligned"
}
$myArr += $Details
}
}
$myArr | Export-CSV -NoTypeInformation "C:\users\a411882\Documents\Scripts\PartitionAlignment.csv"
Would anyone know what is wrong with my code? I'm still learning about partitions so I'm not sure how I need to check the starting off-set number to verify alignment.
You're passing a virtual machine object instead of a string to get-wmiObject -ComputerName. When I do that, get-wmiObject throws an RPC error. You might try -computerName $vm.guest.Hostname instead of -computerName $vm.
In the commented line, your use of % should return a remainder, which will always be a whole number or zero. Maybe you were expecting a quotient instead, and wanted to evaluate if it's an integer?
PS C:\temp> (1 / 2) -isnot [int]
True
PS C:\temp> (2 / 1) -isnot [int]
False
Recent Windows OS align their partitions automatically, so there's that. Here's a good post about alignment generally on VMware, including a link to a more detailed discussion of guest partitions.

WMI optimization

I have the following script.
$script:WMIClassNames = `
"CIM_Processor",`
"CIM_PhysicalMemory",`
"Win32_ComputerSystem",`
"CIM_BIOSElement",`
"Win32_OperatingSystem",`
"Win32_NetworkAdapterConfiguration",`
"Win32_Volume",`
"Win32_QuickFixEngineering",`
"CIM_Process",`
"WIN32_Service",`
"WIN32_NTLogEvent"
$script:WMIClassInfo = Get-WmiObject -ComputerName $script:strSysName -Namespace "Root/CIMV2" -List | Select Name | Where-Object {$script:WMIClassNames -contains $_.Name}
When i measure the time of the script, it is taking almost 4 to 10 min to execute this script on remote machines. Can this script be optimized so that the execution time can be reduced?
Thanks for the help.