I was poking around WMI the other day in PowerShell and was intrigued by the Win32_Share class. This is a great way to find out what items are shared on a server such as printers and folders, although it's not limited to those types of resources. I thought this would make a useful function; one that you might use to audit a collection of computers.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
The function, Get-ShareResource, takes a computername as a parameter, but it defaults to the local computername. I didn't add support for alternate credentials so if connecting to a remote machine you'll need to make sure you have admin rights on the computer. You could add support for alternate credentials if you are so inclined. Here's the main part of the function.
[cc lang="PowerShell"]
Function Get-ShareResource {
[cmdletbinding()]
Param(
[Parameter(Position=0,ValuefromPipeline=$True)]
[Alias("Name")]
[string[]]$Computername=$env:computername
)
Begin {
Write-Verbose "Starting $($myinvocation.mycommand)"
}
Process {
Foreach ($computer in $computername) {
Write-Verbose "Querying $($computer.ToUpper())"
Try {
Get-WmiObject -Class Win32_Share -ComputerName $Computername -erroraction "Stop" |
Select Name,Path,Description,Status,
@{Name="Type";Expression={
Switch ($_.Type) {
0 {"File"}
1 {"Printer"}
2 {"Device"}
3 {"IPC"}
2147483648 {"AdminDisk"}
2147483649 {"AdminPrint"}
2147483650 {"AdminDevice"}
2147483651 {"AdminIPC"}
Default {$_.Type}
}
}},
@{Name="Hidden";Expression={
#use a regular expression and check if the name ends in a $
#which indicates a hidden share
if ($_.Name -match "[\$]$") {
$True
}
else {
$False
}
}},
@{Name="Computername";Expression={$_.__SERVER}}
}
Catch {
$msg="Failed to get share information from {0}. {1}" -f $($computer.ToUpper()),$_.Exception.Message
Write-Warning -Message $msg
}
}#foreach
} #process
End {
Write-Verbose "Ending $($myinvocation.mycommand)"
}
} #end function
[/cc]
The core command is a Get-WmiObject expression to retrieve all instances of the Win32_Share class from the specified computer.
[cc lang="PowerShell"]
Try {
Get-WmiObject -Class Win32_Share -ComputerName $Computername -erroraction "Stop"
[/cc]
But I then select a few properties to write to the pipeline. I also "convert" a few properties into more meaningful values. For example, the Type property is a numeric value so I use a Switch construct to create a "better" value.
[cc lang="PowerShell"]
Select Name,Path,Description,Status,
@{Name="Type";Expression={
Switch ($_.Type) {
0 {"File"}
1 {"Printer"}
2 {"Device"}
3 {"IPC"}
2147483648 {"AdminDisk"}
2147483649 {"AdminPrint"}
2147483650 {"AdminDevice"}
2147483651 {"AdminIPC"}
Default {$_.Type}
}
}},
[/cc]
If you're wondering where I got the values, I looked up the Win32_Share class on MSDN. I also thought it would be handy to have a boolean value to check if share is hidden or not. A hidden share name will end in a $ so I use a regular expression comparison.
[cc lang="PowerShell"]
@{Name="Hidden";Expression={
#use a regular expression and check if the name ends in a $
#which indicates a hidden share
if ($_.Name -match "[\$]$") {
$True
}
else {
$False
}
}},
[/cc]
The last custom property is for the computername. The class itself lacks a property but I can always use the system class, __SERVER.
[cc lang="PowerShell"]
@{Name="Computername";Expression={$_.__SERVER}}
[/cc]
So, assuming I don't run into errors getting the WMI objects, I end up with results like this:
[cc lang="DOS"]
PS S:\> get-shareresource
Name : ADMIN$
Path : C:\Windows
Description : Remote Admin
Status : OK
Type : AdminDisk
Hidden : True
Computername : SERENITY
Name : C$
Path : C:\
Description : Default share
Status : OK
Type : AdminDisk
Hidden : True
Computername : SERENITY
Name : Download$
Path : c:\users\jeff\downloads
Description :
Status : OK
Type : File
Hidden : True
Computername : SERENITY
Name : E$
Path : E:\
Description : Default share
Status : OK
Type : AdminDisk
Hidden : True
Computername : SERENITY
Name : IPC$
Path :
Description : Remote IPC
Status : OK
Type : AdminIPC
Hidden : True
Computername : SERENITY
Name : print$
Path : C:\Windows\system32\spool\drivers
Description : Printer Drivers
Status : OK
Type : File
Hidden : True
Computername : SERENITY
Name : Users
Path : C:\Users
Description :
Status : OK
Type : File
Hidden : False
Computername : SERENITY
[/cc]
The computername parameter can accept pipelined input so it's pretty easy to create an audit report.
[cc lang="DOS"]
PS C:\> Get-Content c:\work\computers.txt | Get-ShareResource | Export-CSV c:\work\ShareAudit.csv
[/cc]
This isn't an especially fancy function, but I hope you'll pick up on using Switch to "decode" and provide more meaningful information.
Download Get-ShareResource and let me know what you think.
Excellent. I needed this last week. I wanted to post the link to someone who had asled the question.
As usual I am too late.
Keep up the good blogginh.