Overview of the SMBShare Module for PowerShell 3

The SMBShare Module that comes with PowerShell 3 lets you administer network shares directly from within PowerShell. The cmdlets are easy to use, and it is my new favorite way to work with network shares.

It’s the Quickest Way to Create a Network Share with PowerShell

It’s very easy to create network shares with PowerShell by using the SMBShare module that comes in PowerShell version 3.

How to Install the SMBShare Module for PowerShell 3

If you’ve already got PowerShell v.3, then you’re already all set.  You don’t even have to add a pssnapin or import a module.  One of my favorite PowerShell 3 features is the ability to load modules on demand when one of the commands in the module is called.

So if you want to load the SMBShare module, just run one of the commands I’m getting ready to tell you about!

The SMBShare “Get-” Commands

The SMBShare module includes 11 different Get commands, for finding out the current state of affairs with your SMB shares and your SMB client configuration.

Get-SmbClientConfiguration:  This will tell you how a computer, either locally or remote through WMI connection, is configured.  It returns items such as how long to stay connected (KeepConn) and how soon to consider a dropped session a timeout (SessionTimeout).

Get-SmbClientNetworkInterface: All of the Network Interfaces, including wired, wireless, and logical, are all displayed.  this makes:
[code language=”powershell”]
#Get all of the IP addresses for all network interfaces
$AllIPs  = Get-SMBClientNetworkInterfaces | Select-Object -ExpandProperty  IPAddresses
Get-SmbConnection:  This lists active SMB connections and even includes Bytes Sent and Received.  Administrative PowerShell session  required.

Hey, have you seen the cool trick I use to color my administrative shells with a red background?  It’s really easy.

Read: How to Change Background Color on Administrative PowerShell Session

Get-SmbMapping  gives you a list of mapped drives, and returns properties such as LocalDrive (the drive letter the mapped drive is assigned) and the RemotePath, which is the mapped network share.  It also displays the status.

Here’s hoping that I can finally and easily remove old sessions to servers to I can connect to an administrative share without getting the stupid “Cannot connect with more than one user name to a server” error.  BTW, in case you didn’t know about it, there’s a sneaky trick to get a second set of credentials mapped to a server share

Get-SmbMultichannelConnection  If you’re using SMB Multichannel, then this is your tool of choice for getting that connection information.  I’m not using it, so I’ll leave it open.  If you’ve got some information about this, please send a note in the comments and I’ll update with your facts and give you credit.

Get-SmbOpenFile I love this one!  Gets all of the files that are currently open.  This was available in the Server properties through the GUI, but this is an administrative function that was a hassle to script in WMI and it’s so much easier now.

Get-SmbServerConfiguration Similar to the first command we mentioned, but this is the server settings instead of the client settings

Get-SmbShare All shares, including administrative and hidden shares, are included with this simple command.    You can quickly see at a glance which of your shares are temporary, permanent, using shadow copy, and its status.  Another one that makes an admins job much easier.

Get-SmbShareAccess  You were probably already asking the question:  ”Does Get-SMBShare tell you who has access?”   But no, it doesn’t.  Instead, you use the Get-SMBShare command, then pipe it into Get-SMBShareAccess
[code language=”powershell”]
#Get a list of any users that write to any shares that are not online

$Shares = Get-SMBShare

$Offline = $Shares | Where-Object {$_.ShareState -eq “Offline”}

$Users = $Offline  | Get-SMBShareAccess | Where-Object {$_.AccessRight -le “Change”}
That’s just the Get Commands, but I think you can tell a lot from the Get commands, because that’s what’s going to feed into the Set commands.

Still, I bet you’d like to know which of the nouns you’ll be able to modify using the SMBShare module.

Set, New, and Remove – the rest of the SMBShare module cmdlets.

By the nouns, that is, the objects that you’re able to administer, here is what you can do to the different SMBShare objects.

SMBClientConfiguration: In addition to Get-, you can also use Set-SMBClientConfiguration.

SMBShare: You can also use New-SMBShare, Remove-SMBShare, and Set-SMBShare.

SMBMultichannelConnection: Update-SMBMultichannelConnection is the only additional cmdlet for working with the Multi-channel SMB connections.

SMBServerConfiguration: Like client configuration, you also get Set-SMBServerConfiguration.

SMBOpenFile: If you were excited to see the Get-SMBOpenFile, you were probably eagerly hoping that this command was included.  Yes, you also get Close-SMBOpenFile.

SMBShareAccess: Also available for administering share permissions is Block-SMBShareAccess, Grant-SMBShareAccess, Revoke-SMBShareAccess, and Unblock-SMShareAccess.

SMBMapping: New-SMBMapping and Remove-SMBMapping are also available, so you can now actually map real drives from within PowerShell, not just PSDrives that exist only in the PowerShell session.

SMBSession: When you’re ready to end a session, you can do it with style using the Close-SMBSession cmdlet.

In Ending

Well, it’s been a great journey, and this exercise was as good for me to learn as it was for you to learn.  While I had already been using some of the SMBShare commands, actually taking the time to try the different cmdlets and seeing which ones are available is really beneficial.

My favorite two that I’ll use the most:



What about you?  What’s your favorite from this module?  Let me know if you liked this article by connecting in the comments below, and please subscribe.

How To Create a Network Share With PowerShell

PowerShell 3 makes it very easy to create a network share in Windows 8 and Windows Server 2012.  PowerShell 3 brings with it a whole plethora of new commands.  Most of the new cmdlets in PowerShell 3 are grouped together into modules that are easy to browse and load.

Creating a new network share is done with the SMBShare module.  You do not need to load the module as you would have in previous versions of PowerShell.  Cmdlets in unloaded modules are listed in the get-command results, and the module is loaded the first time one of the cmdlets is run.

How to Create a Network Share with PowerShell 3

To begin, you’ll need a folder to share.  This is created with the New-Item cmdlet, instead of a cmdlet in the SMBShare module.

New-Item “C:\Shared" –type directory

If you are creating multiple levels at once (like “C:\NewRootFolder\NewChildFolder\NewShared” you can add the –force switch to make it create all necessary parent folders in the heirarchy)

Now that you have a folder that you want to share, you can turn it into a shared folder using the New-SMBShare cmdlet.

New-SMBShare –Name “Shared” –Path “C:\Shared” `
 –ContinuouslyAvailable `
 –FullAccess domain\admingroup  ` 
 -ChangeAccess domain\deptusers `
 -ReadAccess “domain\authenticated users”

Create a Network Share with PowerShell – The Parameters

Here are the parameters that you may need to get just the right experience for your network shares.

Parameter Name Input Type Required Description
CATimeout Integer No How many seconds to wait before failing.
CachingMode Choice:
None, Manual, Documents, Programs, BranchCache, Unknown
No The caching policy for the share.
ChangeAccess String or String Array No Users to grant Read/Write access to.
Concurrent User Limit Integer No How many users can access the share at a time.
ContinuouslyAvailable Boolean (switch) No Whether to keep the share after the next reboot.
Description String No Friendly description of the share.
EncryptData Boolean (switch) No Use to turn on file encryption.
FolderEnumerationMode Choice:
AccessBased, Unrestricted
No Choose when folders are enumerated (listed) in the share.
FullAccess String or String Array No Users to grant Full control to.
Name String Yes Name of the share.
NoAccess String or String Array No Users to deny access to.
Path String Yes The file path to the shared folder.
ReadAccess String or String Array No Users to grant Read Only access to.
ScopeName String No Name of the endpoint that the share is scoped to.
Temporary Boolean (switch) No Share removed after reboot.
ThrottleLimit Integer No Limit the resources of the share.
AsJob Boolean (switch) No Create a Job to background process this command


How To Change or Remove Network Shares with PowerShell

Here are the other cmdlets in the SMBShare module:

  • Block-SmbShareAccess
  • Close-SmbOpenFile
  • Close-SmbSession
  • Get-SmbClientConfiguration
  • Get-SmbClientNetworkInterface
  • Get-SmbConnection
  • Get-SmbMapping
  • Get-SmbMultichannelConnection
  • Get-SmbOpenFile
  • Get-SmbServerConfiguration
  • Get-SmbServerNetworkInterface
  • Get-SmbSession
  • Get-SmbShare
  • Get-SmbShareAccess
  • Grant-SmbShareAccess
  • New-SmbMapping
  • New-SmbShare
  • Remove-SmbMapping
  • Remove-SmbShare
  • Revoke-SmbShareAccess
  • Set-SmbClientConfiguration
  • Set-SmbServerConfiguration
  • Set-SmbShare
  • Unblock-SmbShareAccess
  • Update-SmbMultichannelConnection

I hope this has helped you in your day!

Moved to America, New Job Started

Okay, technically speaking Alaska is in America, so I was already “in America” – but there was no Jack in the Box or Arby’s in Fairbanks – so does it really count?

My PowerShell skills helped me get my new job, and I’m happy to say that it’s in a place that’s much easier to live in than Fairbanks.  My new job is with UC Santa Barbara.  It’s warm and sunny here a lot.

I’m also happy that in my new role as Senior System Engineer, I’ll be focusing on some Microsoft Implementations.  First up, I’ll be getting Forefront Identity Manager 2010 moved from development to production (by way of test) and then getting SharePoint off the ground.  Both of which will include plenty of scripting with PowerShell.

I wonder what they’ll have me do in the second week?

Seriously, it’s a great job in a great location.  I couldn’t be happier – and I owe it all to God and to PowerShell (but I did a little to help, too.)

How To Run Scripts With PowerShell

If you’re new to PowerShell, some of the first things you’ll want to do are find your way around, find the commands, aliases.  Some of the concepts, like figuring out the pipe, and how to use it, can be a struggle.

Before long, though, you’re going to start getting used to it, and then you’ll want to start saving your work so you can reuse it.  You can do that by saving a text file with a .ps1 extension.  A ps1 is just a PowerShell script.  You don’t have to have anything else in it other than the same commands you use when you’re typing in to the PowerShell console.  In fact, anything that you can type into the console can be typed into a .ps1 file exactly the same way, and then run.

So this is for my PowerShell people that are just getting to know their way around, and need to start either working with PowerShell profiles or start running PS1 files.  Once you’ve gotten the script doing what you want, you can also run a PowerShell script as a scheduled task.

Here are some things you can (and should) do to work with ps1 files, including your profile:


Tip 1:  Set the Execution Policy on One Machine (Use Group Policy for a Domain)

PowerShell takes security seriously.  By default, you cannot run scripts at all, not even your profile.  The execution policy defines what scripts you can run.

There are four settings for the execution policy.  You can set this to whatever you like, but it may have already been set for you in your environment via group policy.  Here are the different settings you can set the execution policy to, from most restrictive to least

An execution policy is applied to a scope.  There are three scopes you can apply the policy setting to:  LocalMachine (the computer), CurrentUser (the user), or Process (the currently running PowerShell session and the policy goes away once the window is closed.)  If you don’t specify a scope, you’re setting the LocalMachine policy.  Also, there is a preference in applying scopes:  Process overrides CurrentUser, which in turn overrides LocalMachine.

  • Undefined – If all scopes are undefined then it is set to the default, which is restricted.
  • Restricted – No scripts may run at all.
  • AllSigned – All scripts that have a digital signature may run.
  • RemoteSigned – Local scripts may run.  Scripts executed from the network must be digitally signed.
  • Unrestricted – All scripts may run.
  • Bypass – All scripts may run, and all warnings and prompts are disabled.

Which execution policy you set is up to you.  Usually a prudent choice is RemoteSigned.  Here’s how you set it

Set-ExecutionPolicy  RemoteSigned

Easy, right?  Well without setting the execution policy, all of your scripts, even your own profile, won’t run at all.

Tip 2: Save Work You Will Use Again in a Script

If you’re not already using the Integrated Scripting Environment (ISE), you should really get to know it.

When you go to start PowerShell, instead look for the option to start PowerShell ISE.  Using the ISE gives you an opportunity to save the work that you’ve been doing often, and you can run bits and pieces of your script as you’re writing it to make sure it’s working as you intend.

Tip 3: Use a PowerShell Profile

If you are starting to get into writing down the things you do, you should look at creating a profile.  The profiles (there are multiples actually) are very useful for defining functions, mapping PSDrives, and importing modules.  If you haven’t setup your profile yet, I’ve written a post outlining how to setup your PowerShell profile

Tip 4: Use Comments, Even For Scripts Only You Will Use

When typing out your scripts into a ps1 file, it’s a great idea to use comments liberally.  Even if you think you will not be sharing this script with others, you will likely be sharing it with yourself 6 months after you wrote it.  The things that you thought would always be obvious suddenly are not.  You can save yourself a lot of frustration and time decoding your own scripts if you just add some comments throughout the script describing what you’re attempting to do with it.

The comment character for PowerShell is the Number Sign (Pound Sign, or #).  Anything written after a # in a PowerShell script file (ps1), or even in the console, are not processed but instead passed over.

You can easily comment out a single line of your script by placing a “#” at the beginning of it, like this:

# Write-Host “This Line is a comment.  It won’t write anything”
# This is a comment too.

# Comments can be used at the end of a single line to describe what is happening

$myVariable = 2 + 4    # This should set $myVariable to 6.

You can also comment with a comment block.  Anything written (even on multiple lines) is commented out.  A comment block starts with <#, and then anything after that is a comment until the comment block ends with a #>

<# This is a comment block

Still a comment

This is the last comment line #>

Write-host “Uncommented now”

I hope this is a help to those of you just starting out with PowerShell, and that it helps move you from just starting out, to taking the next steps towards automating with Windows PowerShell.

How To Find Which Cmdlets Have No Alias

Finding cmdlets that already have aliases is really easy.  You can use the Get-Alias cmdlet to find them.

gal | select definition –unique

# “Gal” is an alias for Get-Alias. “Select” is an alias for Select-Object 

If you want to speed up your time at the console, you should consider finding ways to type less.  That can be done by creating aliases.  There are already a lot of aliases, but here’s how to find all the cmdlets that do not yet have an alias.

Continue reading “How To Find Which Cmdlets Have No Alias”

How To Update Configuration Manager Site Code With PowerShell

Did you move domains recently or reconfigure your System Center Configuration Manager (SCCM)?  Maybe you’ve found your Config Manager site code broken.  Here’s a one-liner that shows you How to update a sitecode for SCCM with PowerShell.

This assumes that you’ve got SCCM running, and installed on the client.  I found this problem hanging around on our machines after a migration from an old domain into the new domain.  Each domain had Microsoft Configuration Manager installed on it, and each domain had a different site code.  A domain wide group policy was used to install the client in each domain, but I had problems with the site code for the old domain still on the Configuration Manager client after domain migration was complete.

Luckily, we can use PowerShell to change the site code, and we can even use PowerShell to discover published site codes. 



First we need to grab hold of our SMS client.  In PowerShell, it couldn’t be easier:

$sms = new-object –comobject “Microsoft.SMS.Client”

We can use the methods of the Microsoft.SMS.Client class by using PowerShell to directly work with the SMS client object:


or find out what the site code is currently set to:

$sms.GetAssignedSite()       # This returns a string value

Since the GetAssignedSite() method returns a string, it can be used in scripts to verify the site code is correct.  I use this on scripts (pushed via Group Policy on the domain roots) to verify the site code is correct, and correct the site code automatically if it is wrong.

Since I know the site code, let’s say “ABC” is the new domain and “XYZ” is the old domain, I would use this:

$sms = new-object –comobject “Microsoft.SMS.Client”

if ($sms.GetAssignedSite() –ne “ABC”) { $sms.SetAssignedSite(“ABC”) }

Finally, I’ll call attention to another method of the SMS Client object:  AutoDiscoverSite()

AutoDiscoverSite returns a site code for the Active Directory Domain (if published)

$sms = new-object –comobject “Microsoft.SMS.Client”

if ($sms.GetAssignedSite() –ne $sms.AutoDiscoverSite() ) { $sms.SetAssignedSite($sms.AutoDiscoverSite()) }

Now just a little clean up here…

Write-host “Thanks for reading.  Subscribe! Or, connect via Twitter  or Facebook.  Ask questions to twitter using #poshhelp or #powershell to get q’s answered fast!”

$null = $thisBlogPost

Frequently Used PowerShell Oneliner(s) – Kill All Internet Explorer Windows

Because of my self-appointed title as an Ultimate Microsoft Fanman, it really pains me to disclose this One-Liner.  That’s because saying it is a commonly used suggests that Internet Explorer locks up frequently.

Ouch!  That hurt to type!

Truthfully, it could have been said of Firefox if I used it as much as I use IE.  And to be fair, Internet Explorer might not lock up as much if I didn’t abuse it by keeping 25 windows open all the time, and continue to upgrade to the most recent beta version I can get my PowerShell-scripting hands on.

So when I get stuck, I dropped this One-Liner out there.  It works great, even if the IE window is not responding to close requests through the taskbar, or through the close button on the application itself.  This kills every Internet Explorer window

get-process iexplore | stop-process

You can exercise more surgical precision by going for only the top processor intensive process (or processes if you change “–First 1” to “-First 2”)

get-process iexplore | sort –descending cpu | select –First 1 | stop-process

Or by going for only the Internet Explorer windows with active threads

get-process iexplore | ? {$_.threads | ? {$_.threadstate –eq “Running”} } | stop-process

I really like this method the most.  The thing that gives it an extra edge over the other methods is that if it kills open tabs but not all the tabs on a window, then the tab is reopened automatically.  Hopefully it’s enough of a kick in the pants to get the window open.

Have I overlooked something?  How can it be done better?

Automate Dell Support With PowerShell: Open Dell’s Site With System Tag Automatically

Are you tired of entering the system tag information by hand on Dell’s support web site?  You want a fast and easy way to automate Dell support with PowerShell.  I’ll show you how to Automate Dell Support With PowerShell in this life changing series!

This week, we’re learning how to open Dell’s support site with the system tag filled in automatically.

If you previously read my post on getting the Dell System Tag from WMI you may have, like me, come away from it with one big problem.  In the article, I say that you can enter the system tag into Dell’s support page.  That is a little lame, don’t you think?  Audacious, in fact, to suggest that a PowerShell user should have to do anything!

So, with my apologies, here is a very quick improvement to help you get to your Dell Support Page that much faster.

How To Open Dell’s Support Page with the System Tag Already Filled In

function popup-Dellinfo

$systemtag = (gwmi win32_bios).serialnumber      

#Thanks to Jeffrey Snover for pointing out the Win32_BIOS class

$ie = new-object -com "InternetExplorer.Application"

$webaddress= [string]::Format("




Drop that function into PowerShell, or add it to your PowerShell profile.

That’s pretty good, but I think it can be better.

To see it go from this rudimentary function to something more robust come back next week.  Or subscribe to this blog and read it the day it comes out in your RSS reader!