|
# Copyright: (c) 2020, Jordan Borean (@jborean93) <[email protected]> |
|
# MIT License (see LICENSE or https://opensource.org/licenses/MIT) |
|
|
|
Function Get-SmbShareInfo { |
|
<# |
|
.SYNOPSIS |
|
Enumerate shares on a remote host. |
|
|
|
.DESCRIPTION |
|
Enumerate shares on a remote host and returns the name, type, and special remark for those shares. |
|
|
|
.PARAMETER ComputerName |
|
[String] The host to enumerate the shares for. Can be accepted as pipeline input by value. |
|
|
|
.OUTPUTS |
|
[PSCustomObject]@{ |
|
ComouterName = [String]'The computer the share relates to' |
|
Name = [String]'The name of the share' |
|
Type = [Win32Share.ShareType] An flag enum of the share properties, can be |
|
Disk = Disk drive share |
|
PrintQueue = Print queue share |
|
CommunicationDevice = Communication device share |
|
Ipc = Interprocess communication share |
|
Temporary = A temporary share |
|
Special = Typically a special/admin share like IPC$, C$, ADMIN$ |
|
Remark = [String]'More info on the share' |
|
} |
|
|
|
.EXAMPLE |
|
Get-SmbShareInfo -ComputerName some-host |
|
#> |
|
[CmdletBinding()] |
|
param ( |
|
[Parameter(Mandatory=$true, ValueFromPipeline=$true)] |
|
[String] |
|
$ComputerName |
|
) |
|
|
|
begin { |
|
Add-Type -TypeDefinition @' |
|
using System; |
|
using System.Runtime.InteropServices; |
|
|
|
namespace Win32Share |
|
{ |
|
public class NativeHelpers |
|
{ |
|
[StructLayout(LayoutKind.Sequential)] |
|
public struct SHARE_INFO_1 |
|
{ |
|
[MarshalAs(UnmanagedType.LPWStr)] public string shi1_netname; |
|
public ShareType shi1_type; |
|
[MarshalAs(UnmanagedType.LPWStr)] public string shi1_remark; |
|
} |
|
} |
|
|
|
public class NativeMethods |
|
{ |
|
[DllImport("Netapi32.dll")] |
|
public static extern UInt32 NetApiBufferFree( |
|
IntPtr Buffer); |
|
|
|
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] |
|
public static extern Int32 NetShareEnum( |
|
string servername, |
|
UInt32 level, |
|
ref IntPtr bufptr, |
|
UInt32 prefmaxlen, |
|
ref UInt32 entriesread, |
|
ref UInt32 totalentries, |
|
ref UInt32 resume_handle); |
|
} |
|
|
|
[Flags] |
|
public enum ShareType : uint |
|
{ |
|
Disk = 0, |
|
PrintQueue = 1, |
|
CommunicationDevice = 2, |
|
Ipc = 3, |
|
Temporary = 0x40000000, |
|
Special = 0x80000000, |
|
} |
|
} |
|
'@ |
|
} |
|
|
|
process { |
|
$buffer = [IntPtr]::Zero |
|
$read = 0 |
|
$total = 0 |
|
$resume = 0 |
|
|
|
$res = [Win32Share.NativeMethods]::NetShareEnum( |
|
$ComputerName, |
|
1, # SHARE_INFO_1 |
|
[ref]$buffer, |
|
([UInt32]"0xFFFFFFFF"), # MAX_PREFERRED_LENGTH |
|
[ref]$read, |
|
[ref]$total, |
|
[ref]$resume |
|
) |
|
|
|
if ($res -ne 0) { |
|
$exp = [System.ComponentModel.Win32Exception]$res |
|
Write-Error -Message "Failed to enum share for '$ComputerName': $($exp.Message)" -Exception $exp |
|
return |
|
} |
|
|
|
try { |
|
$entryPtr = $buffer |
|
for ($i = 0; $i -lt $total; $i++) { |
|
$shareInfo = [System.Runtime.InteropServices.Marshal]::PtrToStructure($entryPtr, |
|
[Type]([Win32Share.NativeHelpers+SHARE_INFO_1])) |
|
|
|
[PSCustomObject]@{ |
|
ComputerName = $ComputerName |
|
Name = $shareInfo.shi1_netname |
|
Type = $shareInfo.shi1_type |
|
Remark = $shareInfo.shi1_remark |
|
} |
|
|
|
$entryPtr = [IntPtr]::Add($entryPtr, [System.Runtime.InteropServices.Marshal]::SizeOf($shareInfo)) |
|
} |
|
} finally { |
|
$null = [Win32Share.NativeMethods]::NetApiBufferFree($buffer) |
|
} |
|
} |
|
} |
Thanks Jordan for putting this out there! I'm looking at extending it, adding Free Disk Space and Size.
I read through the
SHARE_INFO
struc
s and didn't see that information. Would I need to use GetDiskFreeSpaceW or maybe GetDiskFreeSpaceA or GetDiskFreeSpaceExA?