Advertisement
stephanlinke

Untitled

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