Powershell script for folder's partition - powershell

I'm trying to create a script which takes a folderpath as an argument and displays how full the partition with the folderpath is (0-100%).
In Linux I know of the df -T $directory command, but I cannot find any way of doing this in powershell. Any tips?

You can approximate the output of df -T by using the following Get-CIMINstance call, which queries WMI/CIM for the information you're requesting. As I'm not a linux expert, I'm not certain what specifically makes df -t a special command. If this output doesn't capture what you need, can you provide some more info?
Get-CimInstance Win32_logicaldisk |  Select-Object SystemName,#{Name=‘Drive Letter‘;Expression={$_.DeviceID}},
        #{Name=‘Drive Label’;Expression={$_.VolumeName}},`
#{Name=‘Size(MB)’;Expression={[int]($_.Size / 1MB)}},`
#{Name=‘FreeSpace%’;Expression={[math]::Round($_.FreeSpace / $_.Size,2)*100}} | ft
> SystemName Drive Letter Drive Label Size(MB) FreeSpace%
---------- ------------ ----------- -------- ----------
BEHEMOTH B: Aug 01 2014 172 0
BEHEMOTH C: 171353 10
BEHEMOTH D: Media 953867 20
BEHEMOTH E: Big Betty 2861459 88
BEHEMOTH H: VM 117726 37
BEHEMOTH T: 250 94
UPDATED
Ok, I created a function called df using this code below. You can provide a directory with -t to get the statistics for that particular partition. Otherwise, if run without a param it will give us the disk statistics for the current disk.
Function df {
Param
(
# Param1 help description
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[Alias("t")]
$directory = (get-item (get-location)))
if ($PSBoundParameters.Count -ne 0){$directory = dget-item $directory}
$root = $directory.Root.Name -replace '\\','%'
Get-CimInstance Win32_logicaldisk -Filter ("DeviceID like '$root%'")| Select-Object SystemName,#{Name=‘Drive Letter‘;Expression={$_.DeviceID}},
#{Name=‘Drive Label’;Expression={$_.VolumeName}},`
#{Name=‘Size(MB)’;Expression={"{0:N0}" -f [int]($_.Size / 1MB)}},`
#{Name=‘FreeSpace%’;Expression={[math]::Round($_.FreeSpace / $_.Size,2)*100}} | ft
}
df -t .\SampleDir
>SystemName Drive Letter Drive Label Size(MB) FreeSpace%
---------- ------------ ----------- -------- ----------
DELLBOOK C: OSDisk 243,247 39

Related

Powershell query results list

The Powershell script provides results table below. We need to find out if VM is reachable or not, so I would like to check if "Time" column is not empty.
The question:
How to check if "Time(ms)" has value? how to query any column or row in such a cases in general?
$result = Test-ConnectionAsync "MyVm"
C:\$result
Source Destination IPV4Address IPV6Address Bytes Time(ms)
------ ----------- ----------- ----------- ----- --------
SourceVM MyVM 10.20.20.10 32 207
SourceVM MyVM 10.20.20.10 32 207
SourceVM MyVM 10.20.20.10 32 207
SourceVM MyVM 10.20.20.10 32 207
thank you!
You can use the Where-Object functionality that checks the value of any column of the given row. If you want to find out what column names are supposed to be, use Get-Member to get all the properties or methods of that object.
# Get all the properties of $result[0]
$result[0] | Get-Member
# Among other things, you will ResponseTime as one of the properties you can use.
# Check if Time(ms) has any value. Following will give you only those rows that match the condition
#Original where statement
#$result | Where-Object { $_.ResponseTime -ne $null }
#Updated where statement
$result | Where-Object { $null -ne $_.ResponseTime }

Sort Drives by Free Space in Powershell

I'm trying to sort my drives using Powershell by free space. The purpose of this utility is to re-distribute one disk that is almost full across all the disks that are not as full.
Currently, my powershell script looks like this:
# Retrieves drives from My Computer
$Drives = gdr -PSProvider FileSystem
# Iterates over all drives found
foreach($Drive in $Drives) {
$Drive | Sort-Object -Property Free
}
The output is this:
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
C 151.09 688.31 FileSystem C:\
D 0.05 15.67 FileSystem D:\
F 0.09 2.96 FileSystem F:\
G 0.05 16.43 FileSystem G:\
H 0.03 9.73 FileSystem H:\
I 2.42 65.94 FileSystem I:\
But I'm expecting something like the Free (GB) Column to be sorted ASC
Any clues?
The problem was that I sorting the individual drive and not the collection as pointed out by #johnrsharpe and #Lee_Dailey
This ended up solving my problem:
# Iterates over all drives found
$SortedDrives = $Drives | Sort-Object -Property Used -Descending
foreach ($Drive in $SortedDrives) {
Write-Output $Drive.Name
}

Another grep / awk q, parsing diskpart output

I've googled this a lot and there are a lot of similar questions but I can't figure out how to put them together to make it work for me. Also, the fact that MS decided to leave dynamic volumes out of their PowerShell cmdlets is really frustrating.
In the following code I'm trying to identify that "Disk 2" is dynamic.
PS C:\Windows\system32> echo 'list disk' | diskpart
Microsoft DiskPart version 10.0.14393.0
Copyright (C) 1999-2013 Microsoft Corporation.
On computer: AHPAP2704
DISKPART>
Disk ### Status Size Free Dyn Gpt
-------- ------------- ------- ------- --- ---
Disk 0 Online 65 GB 0 B
Disk 1 Online 20 GB 0 B *
Disk 2 Offline 50 GB 0 B *
Ideally from the output above I'm going to set a variable to identify the dynamic volume (my script will always only have one) so when complete I'm left with something like $DynDisk = 2.
When I pipe the output to Get-Member the only member types containing property in the name are Chars and Length.
Is there an easy way to get the data into an array or a better method? Or, any chance there is some hidden grep and awk like cmdlets out there?
diskpart output isn't trimmed, so you can parse the relevant information from the end of the string, e.g. like this:
$re = 'disk (\d+)\s+(\w+)\s+(\d+ .?b)\s+(\d+ .?b) (.*)'
'list disk' | diskpart | Select-String -Pattern $re | ForEach-Object {
New-Object -Type PSObject -Property #{
ID = [int]$_.Matches.Groups[1].Value
Status = $_.Matches.Groups[2].Value -eq 'online'
Size = $_.Matches.Groups[3].Value
FreeSpace = $_.Matches.Groups[4].Value
Dynamic = $_.Matches.Groups[5].Value.Substring(0, 3).Trim() -eq '*'
GPT = $_.Matches.Groups[5].Value.Substring(4, 3).Trim() -eq '*'
}
}
All I needed was another half hour of googling.
https://gallery.technet.microsoft.com/DiskPartexe-Powershell-0f7a1bab
That script creates 3 objects which have properties I know now to handle

Incorrect total size result from powershell

I'm facing a problem which the result of getdrive is not accurate. Clueless.
As seen in the screenshots below, 10.1.105.203 has a total space of 7.81TB, but from what powershell gives me, it is only roughly 4TB. Pretty confusing here.
You can also use Get-Psdrive to get the size of a drive.
PS C:\> Get-PSDrive -PSProvider filesystem
Name Used (GB) Free (GB) Provider Root
---- --------- --------- -------- ----
C 48.92 195.13 FileSystem C:\
D 30.82 69.18 FileSystem D:\
E .12 121.49 FileSystem E:\
You can always do a little manipulation to achieve multiple things with this, e.g,
PS C:\> Get-PSDrive -PSProvider filesystem | select Name, #{n= 'Used(GB)' ; e = {"{0:N2}" -f ($_.used/1GB)}}, #{n= 'Free
(GB)' ; e = {"{0:N2}" -f ($_.Free/1GB)}}, #{n= 'Total(GB)' ; e = {"{0:N2}" -f (($_.used + $_.Free)/1GB)}} | ft -auto
Name Used(GB) Free(GB) Total(GB)
---- -------- -------- ---------
C 48.92 195.13 244.04
D 30.82 69.18 100.00
E 0.12 121.49 121.62
You're not really using PowerShell. You're using the Windows Scripting Host's object model, the precursor to PowerShell, from PowerShell. Try using either:
C:\PS> Get-Volume
DriveLetter FileSystemLabel FileSystem DriveType HealthStatus SizeRemaining Size
----------- --------------- ---------- --------- ------------ ------------- ----
C NTFS Fixed Healthy 94.34 GB 237.96 GB
Recovery NTFS Fixed Healthy 10.19 MB 300 MB
or
C:\PS> Get-WmiObject Win32_Volume | Format-Table DriveLetter,Capacity,FreeSpace
DriveLetter Capacity FreeSpace
----------- -------- ---------
C: 255505461248 101292863488
314568704 10682368
Full agree with #Keith Hill, with the PowerShell way to get the result. The strange behaviour is that for your drive L:, I can see that the total size is ok for the 10Tb drive, so I would not be surprise if you receive the same results from the new commands.
The next thing, I would check is if quotas are activated on your server.
You can also use :
Get-WmiObject Win32_logicaldisk -filter "driveType=4"

Unable to retrieve physical size of available storage for cluster

I am half way down with my work and now stuck.
I am trying to fetch information about available storage devices for a cluster.
I am able to fetch the list of available storage devices but unable to retrieve the physical disk, available free space, etc of these available storage.
I want like this. Is there any command to fetch physical disk name from Cluster Disk Name or directly can I get the disk details.
For Shared Disk I am able to retrieve the details (Get-ClusterSharedVolume) but not for a non-shared disk.
I want powershell or WMI script for doing so.
You can get this information from WMI, but it takes a couple steps:
$resources = Get-WmiObject -namespace root\MSCluster MSCluster_Resource -filter "Type='Physical Disk'"
$resources | foreach {
$res = $_
$disks = $res.GetRelated("MSCluster_Disk")
$disks | foreach {
$_.GetRelated("MSCluster_DiskPartition") |
select #{N="Name"; E={$res.Name}}, #{N="Status"; E={$res.State}}, Path, VolumeLabel, TotalSize, FreeSpace
}
} | ft
That will give you output like the following:
Name Status Path VolumeLabel TotalSize FreeSpace
---- ------ ---- ----------- --------- ---------
Cluster Disk 2 2 K: New Volume 5220 5163
SQL - FAS3070 SiteB 2 S: MC_SQL 5597 5455
SM Test 2 M: SM Test 1024 992
DTC - FAS3070B 2 F: MC_WITNESS 5346 5289
Cluster Disk Witness 2 E: New Volume 5322 5267
Cluster Disk 1 2 G: MC_DTC 5088 5035
Cluster Disk 3 2 T: SQL 5119 4999
If you don't care about the resource name/status you can skip those steps and jump straight to the partition (and it'll run much quicker):
gwmi -namespace root\MSCluster MSCluster_DiskPartition | ft Path, VolumeLabel, TotalSize, FreeSpace
Edit: Note that the size is in MB and a Status of "2" means that the disk is online.
you can use wmi like this:
Get-WMIObject Win32_LogicalDisk -filter "DriveType=3" | Select DeviceID, FreeSpace
throw in a computername parameter if you wish to do it remotely
HTH,
Matt
PS. for a more readable report you can try this:
Get-WMIObject Win32_LogicalDisk -filter "DriveType=3" |
Select DeviceID, #{Name = "Free Space (%)" ; Expression= {[int] ($_.FreeSpace / $_.Size* 100)}},#{Name = "Free Space (GB)"; Expression = {[int]($_.Freespace / 1GB)}}, #{Name = "Size (GB)"; Expression = {[int]($_.Freespace / 1GB)}}