Listing share permissions for remote shares

Now that you can list shares, how about something a bit more challenging?

Let’s take a look at share permissions. I tried using subinacl.exe to get these for a remote share. But it turns out that it does not always give trustworthy results. It showed read permissions for a share with Read and Change permissions. And let’s not mention the single-string, unicode output! What a nightmare!

Then I took one step back and issued the following command:

Get-WmiObject -ComputerName REMOTESERVER -List | Where { $_ -match “share” }

Turns out there is a WMI class called Win32_LogicalShareSecuritySetting that can help out!

Using Get-Member, I found the methods and properties I needed to make this work. And after some googling for the meaning of the AccessMask numbers, I was all done.

I have attached the script. Rename it to .ps1 and dot-source it, or paste it into your profile. Then give this command a try:


Oh, objects! I love Powershell!

Get-MySharePermissions (rename to .ps1 or copy into profile)


Finding Shares with Powershell

Here’s a handy little function I wrote for enumerating all shares on a remote server:

function Get-MyShares
 $Shares = Get-WmiObject -Class Win32_Share -ComputerName $Server
 $output = @()
 ForEach ($Share in $Shares)
  $fullpath = “\\{0}\{1}” -f $server, $
  Add-Member -MemberType NoteProperty -InputObject $Share -Name FullPath -Value $fullpath
  $output += $Share
 Return $output

Note that I am adding an additional property to the default output of the WMI query. It contains the full path to the share in the format \\server\share.


Powershell Open File Dialog Box

Do you ever require the users of your script to select which file to use?

I do. And it’s no fun trying to do decent error-handling when a user has to type the full path to a file. Nor is it any fun to be that user. So why not use the Windows Forms class of .Net to show the Open File Dialog Box?

Select-FileDialog function (rename to .ps1 or copy into your profile)

User happy. Me happy. You happy?

Really Quick Server Info

Today’s Helpful Function of the Day is a great one to store in your profile. (Don’t know how to create or update your own custom profile? Read this.) It’s syntax is a simple as:


It returns server information such as Operating System Version and Service Pack, Active Directory Description and Parent Container (Organizational Unit) and the Model of the computer (e.g. Proliant DL380 G3).
It also supports the use of wildcards in a server name. It will return the same info for all matches.

All of that in just 4 lines of powershell code. Gotta love it!

Get-MyServer (Rename to .ps1)

Keep Your Server Descriptions Synchronized

Today’s “Helpful Function of the Day” is my attempt to help you keep your server descriptions in sync.

You use it by placing it in your profile, or by dot-sourcing the script, or by adding the function to one of your own scripts. The syntax is:

Check-Description [-ServerName] <YourServer> [-SkipIdentical]

If you would like to check or update the description of one server, first connect to Virtual Center (Connect-VIServer), then run: Check-Description SERVERNAME. The script will return the description from the VI Client (if the server is a vm), from Active Directory (if it is found in AD) and from the registry of the server itself (the so-called Browse Comment). It then displays a menu which allows you to select one description as the correct description. It will then update the other descriptions (unless they are unavailable).

In case you would like to check a big list of servers to see if the descriptions are in sync, you use the command as follows:

Get-QADComputer -SearchRoot “OU=Servers,DC=mydomain,DC=com” -SizeLimit 0 | ForEach { Check-Description $_.Name -SkipIdentical }

This command will process all found servers. You can also process a list of servers from a textfile like so:

Get-Content D:\servers.txt | ForEach { Check-Description $_ -SkipIdentical }

The SkipIdentical switch will cause the script to output the servername and description if the descriptions are all in sync. This will speed up using the script, because it will not ask for your input for each and every server, only for those where the descriptions are not identical.

Check-Description (Rename to .ps1)

Questions and remarks are welcome in the comments!


Build your own PowerShell universe

The PowerShell profile. In essence it’s nothing more than a personal script that runs each time you start PowerShell. But it’s possibilities are endless. But I’ll get to the possibilities later. Let’s first examine whether we have a profile.


Determining the location of your profile is easy. Just look at the value of the $profile variable:

PS D:\> $profile

C:\Documents and Settings\PeetersHJ\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1


Now lets see whether this file exists:

PS D:\> Test-Path $profile



If it returns False, you can easily create it:

PS D:\> New-Item $profile -itemType file


 Directory: Microsoft.PowerShell.Core\FileSystem::C:\Documents and Settings\PeetersHJ\My Documents\WindowsPowerShell


Mode                LastWriteTime     Length Name

—-                ————-     —— —-

-a—         29-4-2008     10:10          0 Microsoft.PowerShell_profile.ps1


Now we can open the file and start editing it. We could browse to the location of the file and double-click it. But hey, we’ve got PowerShell. It makes life easy:

PS D:\> Invoke-Item $profile


What type of commands would you like to run each and every time you start PowerShell?


Maybe you would like to start at the root of your script directory:

Set-Location D:\scripts


How about storing some variables for use in your daily routines:

$weddingday = Get-Date -year 2006 -month 10 -day 13


But the real fun starts when using functions and filters.

A function is a command that optionally takes input and will generate output, while saving you from typing those same lines of code over and over again. A big advantage is that you can use this function in your scripts and only have to change one line of code instead of every occurrence in all your scripts when making modifications.

A filter has the same advantages. It allows you to replace complex scriptblocks and centralize them.


For example:

function Cred


$global:cred = Get-Credential $User


A simple function I use a lot. It asks for credentials and stores them in the $cred variable. It allows me to use -Credential $cred in all subsequent commands that need alternate credentials. The variable $user is defined earlier in my profile as “DOMAIN\adminuser”.


filter PRD


$_.Description -like “*@PRD*”


Filters like this one allow me to filter search results (in this case of AD computers) using the following syntax: |Where {PRD}.


PS: Did you notice the word global in the Cred function? $global:var turns the variable $var into a global variable, which allows it to be used throughout your PowerShell session. Without the global, the variable would only exist during the execution of the function. This can be handy when you need a temporary variable inside your function, instead of a variable that is the result of your function.