Advertisement
stephanlinke

Untitled

May 24th, 2017
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ### Copyright (c) 2012-2014, Svendsen Tech
  2. ### Author: Joakim Svendsen
  3. ### Get-MountPointData v1.2
  4. # ___ ___ _____ ___
  5. #| _ \ _ \_   _/ __|
  6. #|  _/   / | || (_ |
  7. #|_| |_|_\ |_| \___|
  8. # Windows Mounts Sensor
  9.  
  10. # "Change history": 1.0 -> 1.1 = -Credential, -PromptForCredentials and -NoFormat (the latter allows math operations)
  11. # --- " ---:        1.1 -> 1.2 = -IncludeDiskInfo to show physical disk index number (this was not trivial).
  12. # ---------:        1.1 -> 1.3 = Added PRTG output
  13. # Convert from one device ID format to another.
  14. param($computerName)
  15.  
  16. $channelTemplateDiskFree = @"
  17. <result>
  18. <channel>{0}</channel>
  19. <value>{1}</value>
  20. <unit>{2}</unit>
  21. {3}
  22. <Float>0</Float>
  23. </result>
  24. "@
  25. $channelTemplatePercent = @"
  26. <result>
  27. <channel>{0}</channel>
  28. <value>{1}</value>
  29. <unit>{2}</unit>
  30. {3}
  31. <Float>1</Float>
  32. <LimitMode>1</LimitMode>
  33. <LimitMinWarning>25</LimitMinWarning>
  34. <LimitMinError>15</LimitMinError>
  35. </result>
  36. "@
  37.  
  38. $channelTemplateMountedDisks = @"
  39. <result>
  40. <channel>{0}</channel>
  41. <value>{1}</value>
  42. <unit>CustomUnit</unit>
  43. <customunit>Mounts</customunit>
  44. <Float>0</Float>
  45. <LimitMode>1</LimitMode>
  46. <LimitMinError>{2}</LimitMinError>
  47. </result>
  48. "@
  49.  
  50. #<VolumeSize>GigaByte</VolumeSize>
  51.  
  52. function Get-DeviceIDFromMP {
  53.    
  54.     param([Parameter(Mandatory=$true)][string] $VolumeString,
  55.           [Parameter(Mandatory=$true)][string] $Directory)
  56.    
  57.     if ($VolumeString -imatch '^\s*Win32_Volume\.DeviceID="([^"]+)"\s*$') {
  58.         # Return it in the wanted format.
  59.         $Matches[1] -replace '\\{2}', '\'
  60.     }
  61.     else {
  62.         # Return a presumably unique hashtable key if there's no match.
  63.         "Unknown device ID for " + $Directory
  64.     }
  65.    
  66. }
  67.  
  68. # Thanks to Justin Rich (jrich523) for this C# snippet.
  69. # https://jrich523.wordpress.com/2015/02/27/powershell-getting-the-disk-drive-from-a-volume-or-mount-point/
  70. $STGetDiskClass = @"
  71. using System;
  72. using Microsoft.Win32.SafeHandles;
  73. using System.IO;
  74. using System.Runtime.InteropServices;
  75.  
  76. public class STGetDisk
  77. {
  78.    private const uint IoctlVolumeGetVolumeDiskExtents = 0x560000;
  79.  
  80.    [StructLayout(LayoutKind.Sequential)]
  81.    public struct DiskExtent
  82.    {
  83.        public int DiskNumber;
  84.        public Int64 StartingOffset;
  85.        public Int64 ExtentLength;
  86.    }
  87.  
  88.    [StructLayout(LayoutKind.Sequential)]
  89.    public struct DiskExtents
  90.    {
  91.        public int numberOfExtents;
  92.        public DiskExtent first;
  93.    }
  94.  
  95.    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  96.    private static extern SafeFileHandle CreateFile(
  97.    string lpFileName,
  98.    [MarshalAs(UnmanagedType.U4)] FileAccess dwDesiredAccess,
  99.    [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode,
  100.    IntPtr lpSecurityAttributes,
  101.    [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition,
  102.    [MarshalAs(UnmanagedType.U4)] FileAttributes dwFlagsAndAttributes,
  103.    IntPtr hTemplateFile);
  104.  
  105.    [DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)]
  106.    private static extern bool DeviceIoControl(
  107.    SafeFileHandle hDevice,
  108.    uint IoControlCode,
  109.    [MarshalAs(UnmanagedType.AsAny)] [In] object InBuffer,
  110.    uint nInBufferSize,
  111.    ref DiskExtents OutBuffer,
  112.    int nOutBufferSize,
  113.    ref uint pBytesReturned,
  114.    IntPtr Overlapped
  115.    );
  116.  
  117.    public static string GetPhysicalDriveString(string path)
  118.    {
  119.        //clean path up
  120.        path = path.TrimEnd('\\');
  121.        if (!path.StartsWith(@"\\.\"))
  122.            path = @"\\.\" + path;
  123.  
  124.        SafeFileHandle shwnd = CreateFile(path, FileAccess.Read, FileShare.Read | FileShare.Write, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
  125.        if (shwnd.IsInvalid)
  126.        {
  127.            //Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
  128.            Exception e = Marshal.GetExceptionForHR(Marshal.GetLastWin32Error());
  129.        }
  130.  
  131.        uint bytesReturned = new uint();
  132.        DiskExtents de1 = new DiskExtents();
  133.        bool result = DeviceIoControl(shwnd, IoctlVolumeGetVolumeDiskExtents, IntPtr.Zero, 0, ref de1, Marshal.SizeOf(de1), ref bytesReturned, IntPtr.Zero);
  134.        shwnd.Close();
  135.  
  136.        if (result)
  137.            return @"\\.\PhysicalDrive" + de1.first.DiskNumber;
  138.        return null;
  139.    }
  140. }
  141. "@
  142. try {
  143.     Add-Type -TypeDefinition $STGetDiskClass -ErrorAction Stop
  144. }
  145. catch {
  146.     if (-not $Error[0].Exception -like '*The type name * already exists*') {
  147.         Write-Warning -Message "Error adding [STGetDisk] class locally."
  148.     }
  149. }
  150.  
  151. function Get-MountPointData {
  152.    
  153.     [CmdletBinding(
  154.         DefaultParameterSetName='NoPrompt'
  155.     )]
  156.     param(
  157.         [Parameter(Mandatory=$true)][string[]] $ComputerName,
  158.         [Parameter(ParameterSetName='Prompt')][switch] $PromptForCredentials,
  159.         [Parameter(ParameterSetName='NoPrompt')][System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty,
  160.         [switch] $IncludeRootDrives,
  161.         [switch] $NoFormat,
  162.         [switch] $IncludeDiskInfo
  163.     )
  164.    
  165.     foreach ($Computer in $ComputerName) {
  166.        
  167.         $WmiHash = @{
  168.             ComputerName = $Computer
  169.             ErrorAction  = 'Stop'
  170.         }
  171.         #if ($PromptForCredentials -and $Credential.Username) {
  172.         #    Write-Warning "You specified both -PromptForCredentials and -Credential. Prompting overrides."
  173.         #}
  174.         if ($PSCmdlet.ParameterSetName -eq 'Prompt') {
  175.             $WmiHash.Credential = Get-Credential
  176.         }
  177.         elseif ($Credential.Username) {
  178.             $WmiHash.Credential = $Credential
  179.         }
  180.         try {
  181.             # Collect mount point device IDs and populate a hashtable with IDs as keys
  182.             $MountPointData = @{}
  183.             Get-WmiObject @WmiHash -Class Win32_MountPoint |
  184.                 Where-Object {
  185.                     if ($IncludeRootDrives) {
  186.                         $true
  187.                     }
  188.                     else {
  189.                         $_.Directory -NotMatch '^\s*Win32_Directory\.Name="[a-z]:\\{2}"\s*$'
  190.                     }
  191.                 } |
  192.                 ForEach-Object {
  193.                     $MountPointData.(Get-DeviceIDFromMP -VolumeString $_.Volume -Directory $_.Directory) = $_.Directory
  194.             }
  195.             $Volumes = @(Get-WmiObject @WmiHash -Class Win32_Volume | Where-Object {
  196.                     if ($IncludeRootDrives) { $true } else { -not $_.DriveLetter }
  197.                 } |
  198.                 Select-Object Label, Caption, Capacity, FreeSpace, FileSystem, DeviceID, @{n='Computer';e={$Computer}} )
  199.         }
  200.         catch {
  201.             Write-Error "${Computer}: Terminating WMI error (skipping): $_"
  202.             continue
  203.         }
  204.         if (-not $Volumes.Count) {
  205.             Write-Error "${Computer}: No mount points found. Skipping."
  206.             continue
  207.         }
  208.         if ($PSBoundParameters['IncludeDiskInfo']) {
  209.             $DiskDriveWmiInfo = Get-WmiObject @WmiHash -Class Win32_DiskDrive
  210.         }
  211.         $Volumes | ForEach-Object {
  212.             if ($MountPointData.ContainsKey($_.DeviceID)) {
  213.                 # Let's avoid dividing by zero, it's so disruptive.
  214.                 if ($_.Capacity) {
  215.                     $PercentFree = $_.FreeSpace*100/$_.Capacity
  216.                 }
  217.                 else {
  218.                     $PercentFree = 0
  219.                 }
  220.                 $_ | Select-Object -Property DeviceID, Computer, Label, Caption, FileSystem, @{n='Size (GB)';e={$_.Capacity/1GB}},
  221.                     @{n='Free space';e={$_.FreeSpace}}, @{n='Percent free';e={$PercentFree}}
  222.             }
  223.         } | Sort-Object -Property 'Percent free', @{Descending=$true;e={$_.'Size (GB)'}}, Label, Caption |
  224.             Select-Object -Property $(if ($NoFormat) {
  225.                 @{n='ComputerName'; e={$_.Computer}},
  226.                 @{n='Label';        e={$_.Label}},
  227.                 @{n='Caption';      e={$_.Caption}},
  228.                 @{n='FileSystem';   e={$_.FileSystem}},
  229.                 @{n='Size (GB)';    e={$_.'Size (GB)'}},
  230.                 @{n='Free space';   e={$_.'Free space'}},
  231.                 @{n='Percent free'; e={$_.'Percent free'}},
  232.                 $(if ($PSBoundParameters['IncludeDiskInfo']) {
  233.                     @{n='Disk Index'; e={
  234.                         try {
  235.                             $ScriptBlock = {
  236.                                 param($GetDiskClass, $DriveString)
  237.                                 try {
  238.                                     Add-Type -TypeDefinition $GetDiskClass -ErrorAction Stop
  239.                                 }
  240.                                 catch {
  241.                                     #Write-Error -Message "${Computer}: Error creating class [STGetDisk]"
  242.                                     return "Error creating [STGetDisk] class: $_"
  243.                                 }
  244.                                 return [STGetDisk]::GetPhysicalDriveString($DriveString)
  245.                             }
  246.                             if ($Credential.Username) {
  247.                                 $PhysicalDisk = Invoke-Command -ComputerName $Computer -Credential $Credential -ScriptBlock $ScriptBlock -ArgumentList $STGetDiskClass, $(if ($_.Caption -imatch '\A[a-z]:\\\z') { $_.Caption } else { $_.DeviceID.TrimStart('\?') })
  248.                             }
  249.                             else {
  250.                                 $PhysicalDisk = Invoke-Command -ComputerName $Computer -ScriptBlock $ScriptBlock -ArgumentList $STGetDiskClass, $(if ($_.Caption -imatch '\A[a-z]:\\\z') { $_.Caption } else { $_.DeviceID.TrimStart('\?') })
  251.                             }
  252.                             if ($PhysicalDisk -like 'Error*') {
  253.                                 "Error: $PhysicalDisk"
  254.                             }
  255.                             else {
  256.                                 ($DiskDriveWmiInfo | Where-Object { $PhysicalDisk } | Where-Object { $PhysicalDisk.Trim() -eq $_.Name } | Select-Object -ExpandProperty Index) -join '; '
  257.                             }
  258.                         }
  259.                         catch {
  260.                             "Error: $_"
  261.                         }
  262.                     } # end of disk index expression
  263.                     } # end of if disk index hashtable
  264.                 }) # end of if includediskinfo parameter subexpression and if
  265.             }
  266.             else {
  267.                 @{n='ComputerName'; e={$_.Computer}},
  268.                 @{n='Label';        e={$_.Label}},
  269.                 @{n='Caption';      e={$_.Caption}},
  270.                 @{n='FileSystem';   e={$_.FileSystem}},
  271.                 @{n='Size (GB)';    e={$_.'Size (GB)'.ToString('N')}},
  272.                 @{n='Free space';   e={$_.'Free space'.ToString('N')}},
  273.                 @{n='Percent free'; e={$_.'Percent free'.ToString('N')}},
  274.                 $(if ($PSBoundParameters['IncludeDiskInfo']) {
  275.                     @{n='Disk Index'; e={
  276.                         try {
  277.                             $ScriptBlock = {
  278.                                 param($GetDiskClass, $DriveString)
  279.                                 try {
  280.                                     Add-Type -TypeDefinition $GetDiskClass -ErrorAction Stop
  281.                                 }
  282.                                 catch {
  283.                                     #Write-Error -Message "${Computer}: Error creating class [STGetDisk]"
  284.                                     return "Error creating [STGetDisk] class: $_"
  285.                                 }
  286.                                 return [STGetDisk]::GetPhysicalDriveString($DriveString)
  287.                             }
  288.                             if ($Credential.Username) {
  289.                                 $PhysicalDisk = Invoke-Command -ComputerName $Computer -Credential $Credential -ScriptBlock $ScriptBlock -ArgumentList $STGetDiskClass, $(if ($_.Caption -imatch '\A[a-z]:\\\z') { $_.Caption } else { $_.DeviceID.TrimStart('\?') })
  290.                             }
  291.                             else {
  292.                                 $PhysicalDisk = Invoke-Command -ComputerName $Computer -ScriptBlock $ScriptBlock -ArgumentList $STGetDiskClass, $(if ($_.Caption -imatch '\A[a-z]:\\\z') { $_.Caption } else { $_.DeviceID.TrimStart('\?') })
  293.                             }
  294.                             if ($PhysicalDisk -like 'Error*') {
  295.                                 "Error: $PhysicalDisk"
  296.                             }
  297.                             else {
  298.                                 ($DiskDriveWmiInfo | Where-Object { $PhysicalDisk } | Where-Object { $PhysicalDisk.Trim() -eq $_.Name } | Select-Object -ExpandProperty Index) -join '; '
  299.                             }
  300.                         }
  301.                         catch {
  302.                             "Error: $_"
  303.                         }
  304.                     } # end of disk index expression
  305.                     } # end of if disk index hashtable
  306.                 }) # end of if includediskinfo parameter subexpression and if
  307.             }) # end of if $NoFormat
  308.     }
  309. }
  310.  
  311. function This-PRTGOut ($computerName) {
  312. [System.Globalization.NumberFormatInfo]::CurrentInfo.NumberGroupSeparator = "";
  313. [System.Globalization.NumberFormatInfo]::CurrentInfo.NumberDecimalSeparator = ".";
  314. $Channels = "";
  315.  
  316. $DiskCount = 0;
  317. $Disks = (Get-MountPointData -ComputerName $ComputerName -IncludeDiskInfo)
  318.  
  319. $Disks | ft -AutoSize
  320.  
  321. foreach($Disk in $Disks)
  322. {
  323.     if($Disk.Label.Length -ne 0){
  324.         $DiskCount++;
  325.         $Channels += ([string]::Format($channelTemplateDiskFree,"[$($Disk.Label)] Free",[double]$Disk."Free Space","BytesDisk","<VolumeSize>GigaByte</VolumeSize>"));
  326.         $Channels += ([string]::Format($channelTemplatePercent,"[$($Disk.Label)] Free %",[int]$Disk."Percent free","Percent",""));
  327.     }
  328. }
  329.  
  330. $channels += ([string]::Format($channelTemplateMountedDisks,"Mounts",$DiskCount,$DiskCount));
  331.  
  332. write-host "<prtg>";
  333. write-host $Channels;
  334. write-host "</prtg>";
  335.  
  336. }
  337.  
  338. This-PRTGOut -computerName $computername;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement