Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ### Copyright (c) 2012-2014, Svendsen Tech
- ### Author: Joakim Svendsen
- ### Get-MountPointData v1.2
- # ___ ___ _____ ___
- #| _ \ _ \_ _/ __|
- #| _/ / | || (_ |
- #|_| |_|_\ |_| \___|
- # Windows Mounts Sensor
- # "Change history": 1.0 -> 1.1 = -Credential, -PromptForCredentials and -NoFormat (the latter allows math operations)
- # --- " ---: 1.1 -> 1.2 = -IncludeDiskInfo to show physical disk index number (this was not trivial).
- # ---------: 1.1 -> 1.3 = Added PRTG output
- # Convert from one device ID format to another.
- param($computerName)
- $channelTemplateDiskFree = @"
- <result>
- <channel>{0}</channel>
- <value>{1}</value>
- <unit>{2}</unit>
- {3}
- <Float>0</Float>
- </result>
- "@
- $channelTemplatePercent = @"
- <result>
- <channel>{0}</channel>
- <value>{1}</value>
- <unit>{2}</unit>
- {3}
- <Float>1</Float>
- <LimitMode>1</LimitMode>
- <LimitMinWarning>25</LimitMinWarning>
- <LimitMinError>15</LimitMinError>
- </result>
- "@
- $channelTemplateMountedDisks = @"
- <result>
- <channel>{0}</channel>
- <value>{1}</value>
- <unit>CustomUnit</unit>
- <customunit>Mounts</customunit>
- <Float>0</Float>
- <LimitMode>1</LimitMode>
- <LimitMinError>{2}</LimitMinError>
- </result>
- "@
- #<VolumeSize>GigaByte</VolumeSize>
- function Get-DeviceIDFromMP {
- param([Parameter(Mandatory=$true)][string] $VolumeString,
- [Parameter(Mandatory=$true)][string] $Directory)
- if ($VolumeString -imatch '^\s*Win32_Volume\.DeviceID="([^"]+)"\s*$') {
- # Return it in the wanted format.
- $Matches[1] -replace '\\{2}', '\'
- }
- else {
- # Return a presumably unique hashtable key if there's no match.
- "Unknown device ID for " + $Directory
- }
- }
- # Thanks to Justin Rich (jrich523) for this C# snippet.
- # https://jrich523.wordpress.com/2015/02/27/powershell-getting-the-disk-drive-from-a-volume-or-mount-point/
- $STGetDiskClass = @"
- using System;
- using Microsoft.Win32.SafeHandles;
- using System.IO;
- using System.Runtime.InteropServices;
- public class STGetDisk
- {
- private const uint IoctlVolumeGetVolumeDiskExtents = 0x560000;
- [StructLayout(LayoutKind.Sequential)]
- public struct DiskExtent
- {
- public int DiskNumber;
- public Int64 StartingOffset;
- public Int64 ExtentLength;
- }
- [StructLayout(LayoutKind.Sequential)]
- public struct DiskExtents
- {
- public int numberOfExtents;
- public DiskExtent first;
- }
- [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
- private static extern SafeFileHandle CreateFile(
- string lpFileName,
- [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
- [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
- IntPtr lpSecurityAttributes,
- [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
- [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
- IntPtr hTemplateFile);
- [DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)]
- private static extern bool DeviceIoControl(
- SafeFileHandle hDevice,
- uint IoControlCode,
- [MarshalAs(UnmanagedType.AsAny)] [In] object InBuffer,
- uint nInBufferSize,
- ref DiskExtents OutBuffer,
- int nOutBufferSize,
- ref uint pBytesReturned,
- IntPtr Overlapped
- );
- public static string GetPhysicalDriveString(string path)
- {
- //clean path up
- path = path.TrimEnd('\\');
- if (!path.StartsWith(@"\\.\"))
- path = @"\\.\" + path;
- SafeFileHandle shwnd = CreateFile(path, FileAccess.Read, FileShare.Read | FileShare.Write, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
- if (shwnd.IsInvalid)
- {
- //Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
- Exception e = Marshal.GetExceptionForHR(Marshal.GetLastWin32Error());
- }
- uint bytesReturned = new uint();
- DiskExtents de1 = new DiskExtents();
- bool result = DeviceIoControl(shwnd, IoctlVolumeGetVolumeDiskExtents, IntPtr.Zero, 0, ref de1, Marshal.SizeOf(de1), ref bytesReturned, IntPtr.Zero);
- shwnd.Close();
- if (result)
- return @"\\.\PhysicalDrive" + de1.first.DiskNumber;
- return null;
- }
- }
- "@
- try {
- Add-Type -TypeDefinition $STGetDiskClass -ErrorAction Stop
- }
- catch {
- if (-not $Error[0].Exception -like '*The type name * already exists*') {
- Write-Warning -Message "Error adding [STGetDisk] class locally."
- }
- }
- function Get-MountPointData {
- [CmdletBinding(
- DefaultParameterSetName='NoPrompt'
- )]
- param(
- [Parameter(Mandatory=$true)][string[]] $ComputerName,
- [Parameter(ParameterSetName='Prompt')][switch] $PromptForCredentials,
- [Parameter(ParameterSetName='NoPrompt')][System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty,
- [switch] $IncludeRootDrives,
- [switch] $NoFormat,
- [switch] $IncludeDiskInfo
- )
- foreach ($Computer in $ComputerName) {
- $WmiHash = @{
- ComputerName = $Computer
- ErrorAction = 'Stop'
- }
- #if ($PromptForCredentials -and $Credential.Username) {
- # Write-Warning "You specified both -PromptForCredentials and -Credential. Prompting overrides."
- #}
- if ($PSCmdlet.ParameterSetName -eq 'Prompt') {
- $WmiHash.Credential = Get-Credential
- }
- elseif ($Credential.Username) {
- $WmiHash.Credential = $Credential
- }
- try {
- # Collect mount point device IDs and populate a hashtable with IDs as keys
- $MountPointData = @{}
- Get-WmiObject @WmiHash -Class Win32_MountPoint |
- Where-Object {
- if ($IncludeRootDrives) {
- $true
- }
- else {
- $_.Directory -NotMatch '^\s*Win32_Directory\.Name="[a-z]:\\{2}"\s*$'
- }
- } |
- ForEach-Object {
- $MountPointData.(Get-DeviceIDFromMP -VolumeString $_.Volume -Directory $_.Directory) = $_.Directory
- }
- $Volumes = @(Get-WmiObject @WmiHash -Class Win32_Volume | Where-Object {
- if ($IncludeRootDrives) { $true } else { -not $_.DriveLetter }
- } |
- Select-Object Label, Caption, Capacity, FreeSpace, FileSystem, DeviceID, @{n='Computer';e={$Computer}} )
- }
- catch {
- Write-Error "${Computer}: Terminating WMI error (skipping): $_"
- continue
- }
- if (-not $Volumes.Count) {
- Write-Error "${Computer}: No mount points found. Skipping."
- continue
- }
- if ($PSBoundParameters['IncludeDiskInfo']) {
- $DiskDriveWmiInfo = Get-WmiObject @WmiHash -Class Win32_DiskDrive
- }
- $Volumes | ForEach-Object {
- if ($MountPointData.ContainsKey($_.DeviceID)) {
- # Let's avoid dividing by zero, it's so disruptive.
- if ($_.Capacity) {
- $PercentFree = $_.FreeSpace*100/$_.Capacity
- }
- else {
- $PercentFree = 0
- }
- $_ | Select-Object -Property DeviceID, Computer, Label, Caption, FileSystem, @{n='Size (GB)';e={$_.Capacity/1GB}},
- @{n='Free space';e={$_.FreeSpace}}, @{n='Percent free';e={$PercentFree}}
- }
- } | Sort-Object -Property 'Percent free', @{Descending=$true;e={$_.'Size (GB)'}}, Label, Caption |
- Select-Object -Property $(if ($NoFormat) {
- @{n='ComputerName'; e={$_.Computer}},
- @{n='Label'; e={$_.Label}},
- @{n='Caption'; e={$_.Caption}},
- @{n='FileSystem'; e={$_.FileSystem}},
- @{n='Size (GB)'; e={$_.'Size (GB)'}},
- @{n='Free space'; e={$_.'Free space'}},
- @{n='Percent free'; e={$_.'Percent free'}},
- $(if ($PSBoundParameters['IncludeDiskInfo']) {
- @{n='Disk Index'; e={
- try {
- $ScriptBlock = {
- param($GetDiskClass, $DriveString)
- try {
- Add-Type -TypeDefinition $GetDiskClass -ErrorAction Stop
- }
- catch {
- #Write-Error -Message "${Computer}: Error creating class [STGetDisk]"
- return "Error creating [STGetDisk] class: $_"
- }
- return [STGetDisk]::GetPhysicalDriveString($DriveString)
- }
- if ($Credential.Username) {
- $PhysicalDisk = Invoke-Command -ComputerName $Computer -Credential $Credential -ScriptBlock $ScriptBlock -ArgumentList $STGetDiskClass, $(if ($_.Caption -imatch '\A[a-z]:\\\z') { $_.Caption } else { $_.DeviceID.TrimStart('\?') })
- }
- else {
- $PhysicalDisk = Invoke-Command -ComputerName $Computer -ScriptBlock $ScriptBlock -ArgumentList $STGetDiskClass, $(if ($_.Caption -imatch '\A[a-z]:\\\z') { $_.Caption } else { $_.DeviceID.TrimStart('\?') })
- }
- if ($PhysicalDisk -like 'Error*') {
- "Error: $PhysicalDisk"
- }
- else {
- ($DiskDriveWmiInfo | Where-Object { $PhysicalDisk } | Where-Object { $PhysicalDisk.Trim() -eq $_.Name } | Select-Object -ExpandProperty Index) -join '; '
- }
- }
- catch {
- "Error: $_"
- }
- } # end of disk index expression
- } # end of if disk index hashtable
- }) # end of if includediskinfo parameter subexpression and if
- }
- else {
- @{n='ComputerName'; e={$_.Computer}},
- @{n='Label'; e={$_.Label}},
- @{n='Caption'; e={$_.Caption}},
- @{n='FileSystem'; e={$_.FileSystem}},
- @{n='Size (GB)'; e={$_.'Size (GB)'.ToString('N')}},
- @{n='Free space'; e={$_.'Free space'.ToString('N')}},
- @{n='Percent free'; e={$_.'Percent free'.ToString('N')}},
- $(if ($PSBoundParameters['IncludeDiskInfo']) {
- @{n='Disk Index'; e={
- try {
- $ScriptBlock = {
- param($GetDiskClass, $DriveString)
- try {
- Add-Type -TypeDefinition $GetDiskClass -ErrorAction Stop
- }
- catch {
- #Write-Error -Message "${Computer}: Error creating class [STGetDisk]"
- return "Error creating [STGetDisk] class: $_"
- }
- return [STGetDisk]::GetPhysicalDriveString($DriveString)
- }
- if ($Credential.Username) {
- $PhysicalDisk = Invoke-Command -ComputerName $Computer -Credential $Credential -ScriptBlock $ScriptBlock -ArgumentList $STGetDiskClass, $(if ($_.Caption -imatch '\A[a-z]:\\\z') { $_.Caption } else { $_.DeviceID.TrimStart('\?') })
- }
- else {
- $PhysicalDisk = Invoke-Command -ComputerName $Computer -ScriptBlock $ScriptBlock -ArgumentList $STGetDiskClass, $(if ($_.Caption -imatch '\A[a-z]:\\\z') { $_.Caption } else { $_.DeviceID.TrimStart('\?') })
- }
- if ($PhysicalDisk -like 'Error*') {
- "Error: $PhysicalDisk"
- }
- else {
- ($DiskDriveWmiInfo | Where-Object { $PhysicalDisk } | Where-Object { $PhysicalDisk.Trim() -eq $_.Name } | Select-Object -ExpandProperty Index) -join '; '
- }
- }
- catch {
- "Error: $_"
- }
- } # end of disk index expression
- } # end of if disk index hashtable
- }) # end of if includediskinfo parameter subexpression and if
- }) # end of if $NoFormat
- }
- }
- function This-PRTGOut ($computerName) {
- [System.Globalization.NumberFormatInfo]::CurrentInfo.NumberGroupSeparator = "";
- [System.Globalization.NumberFormatInfo]::CurrentInfo.NumberDecimalSeparator = ".";
- $Channels = "";
- $DiskCount = 0;
- $Disks = (Get-MountPointData -ComputerName $ComputerName -IncludeDiskInfo)
- $Disks | ft -AutoSize
- foreach($Disk in $Disks)
- {
- if($Disk.Label.Length -ne 0){
- $DiskCount++;
- $Channels += ([string]::Format($channelTemplateDiskFree,"[$($Disk.Label)] Free",[double]$Disk."Free Space","BytesDisk","<VolumeSize>GigaByte</VolumeSize>"));
- $Channels += ([string]::Format($channelTemplatePercent,"[$($Disk.Label)] Free %",[int]$Disk."Percent free","Percent",""));
- }
- }
- $channels += ([string]::Format($channelTemplateMountedDisks,"Mounts",$DiskCount,$DiskCount));
- write-host "<prtg>";
- write-host $Channels;
- write-host "</prtg>";
- }
- This-PRTGOut -computerName $computername;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement