Skip to content

Instantly share code, notes, and snippets.

@jborean93
Created May 6, 2020 19:55
Show Gist options
  • Save jborean93/017d3d890ae8d33276a08d3f5cc7eb45 to your computer and use it in GitHub Desktop.
Save jborean93/017d3d890ae8d33276a08d3f5cc7eb45 to your computer and use it in GitHub Desktop.
Enumerates shares on a remote host
# Copyright: (c) 2020, Jordan Borean (@jborean93) <jborean93@gmail.com>
# 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)
}
}
}
@mattcargile
Copy link

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 strucs and didn't see that information. Would I need to use GetDiskFreeSpaceW or maybe GetDiskFreeSpaceA or GetDiskFreeSpaceExA?

@jborean93
Copy link
Author

Yea I would say either GetDiskSpaceW or GetDiskSpaceExW. Happy to guide you on the Discord if you need help.

@mattcargile
Copy link

mattcargile commented Mar 28, 2023

Just finished my fork. I added some a $Name parameter and $InputObject and accept a [string[]] for `$ComputerName. Thanks for the help in Discord!

The main thing I don't like now is the inner function throwing errors on Access Denied looks uglier and shows a bit too much of the internals. I haven't played with error handling with a function inside of a function too much.

@mattcargile
Copy link

Got some nice formatting to on the disk space with PowerShellHumanizer. Very fun. Thanks so much for this.

@jborean93
Copy link
Author

Nice, feel free to share your copy here so others can see it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment