Create a PSEdit Function to Open a File in a New Tab in PowerShell ISE

Have you used PSEdit to open a file in a new tab in your PowerShell ISE session?


PSEdit is a built-in function that runs only on PowerShell ISE.  It’s simple and easy to use.  Enter in a filename and *poof*, it opens in a new tab of the ISE.  What a great idea! But wait! There’s more! I’m going to share a function that you can use to put PSEdit on your PowerShell console, (not on the ISE), and since you’re not going to be editing in the console, it opens your files in the ISE.

Here’s an example of how PSEdit is used:

#Declare the file you want to edit into a variable (optional)
$FilePath = "C:\Scripts\MyProfile.ps1"

#Run the file
PSEdit $FilePath

This is all because of the function “PSEdit” that leverages the $PSIse system variable. Here’s the code for the function.


    foreach ($filename in $filenames)
        dir $filename | where {!$_.PSIsContainer} | %{
            $psISE.CurrentPowerShellTab.Files.Add($_.FullName) > $null

The only problem is that it’s only available in ISE.  Of course, you don’t really have an editor in a PowerShell console session, and I’m almost always in ISE when I’m wanting to edit… But it might be nice to include that function in a PowerShell console.

If you’d like to add a PSEdit function to your console, begin with opening your PowerShell Profile.  You can even do this from PowerShell ISE, but the PowerShell ISE and the PowerShell regular console do have different profiles.

From the PowerShellISE, this will give you the location of your PowerShell ISE profile.


While this sneaky trick will give you the path to your PowerShell profile.


Most of you could also get that result with Replace(“ISE”,””), but it would fail if your user profile on your computer is in a directory with “ISE” in it.  Maybe your computer account is called “Promise” or something. It could happen.

Next, load up your regular PowerShell profile instead of your ISE profile for editing using the exact same PSEdit command that we covet!

PSEdit $Profile.Replace("PowerShellISE","PowerShell")


Next, drop this function into your profile to create a PSEdit that will accept pipeline input, due some basic error checking. Through luck, I’ve found that using this will not open the same file if it’s already open. I didn’t even have to get fancy, it just already worked.

function PSEdit {

Process {
	if (test-path $filename -PathType Leaf) {
        $file = Get-ChildItem $filename
        if ($file.PSProvider.Name -eq "Filesystem") {
            Start-Process PowerShell_ISE -ArgumentList $file
        else {Write-Error "Wrong PSProvider: $($File.PSProvider.Name)" }
    else {write-error "Bad path: $filename"}   

<# .SYNOPSIS Opens a file in PowerShell ISE for editing. .DESCRIPTION Accepts one or more file (as paths) and then checks them to make sure the path exists and it's a file. If any of the files are not already open in PowerShell ISE, the file is opened in a new tab. .EXAMPLE PSEdit $Filename Opens the file at $filename in the PowerShell ISE .EXAMPLE Get-ChildItem C:\Scripts\ProjectGenesis\*.ps1 | PSEdit Opens all PS1 files in the Project Genesis folder for editing. .LINK #>

I got this idea from Mike Robbins, who wrote a nice post about PSEdit on his blog.

EDIT:  Or, you could have just used the ISE function from the PowerShell console.

Microsoft Virtual Academy Course: Getting Started with PowerShell 3

Microsoft Virtual Academy on PowerShell 3 with Jeffrey Snover Available

Microsoft Virtual Academy has a course on PowerShell 3 that you just can’t miss. This is part one of a series, so don’t fall behind.  The first course is “Getting Started with PowerShell 3.0 Jump Start” and it’s available now.

Microsoft Virtual Academy Course: Getting Started with PowerShell 3

Getting Started with PowerShell 3.0 is presented by Jason Helmick (@TheJasonHelmick) and Jeffrey Snover (@JSnover), who invented PowerShell.

It’s available now as a free course that you can start watching.

The course includes these modules, and provides almost 6 hours of material:

  1. “Don’t Fear the Shell” (39 minutes)
  2. The Help System (55 minutes)
  3. The pipeline: getting connected & extending the shell (28 minutes)
  4. Objects for the admin (42 minutes)
  5. The pipeline: deeper (43 minutes)
  6. The PowerShell in the shell: Remoting (55 minutes)
  7. Getting prepared for automation (26 minutes)
  8. Automation in scale: Remoting (27 minutes)
  9. Introducing scripting and toolmaking (51 minutes)

I’m going through this training now, and though I have a pretty good handle on PowerShell I can still learn a lot in the little details, and it’s great to hear some of the stories from Jeffrey Snover about how PowerShell came out. Stories like:

  • How the pipeline in PowerShell differs from the pipeline in Unix (in Unix the pipeline only passes text, in PowerShell you pass whole objects, with properties and methods included)
  • How the verb-noun command structure came from VMS.
  • Why commands in PowerShell are called cmdlets (searching for “command” returned millions of results, searching for “cmdlet” returned only thousands, and they were all about PowerShell)
  • Why Unix commands work in PowerShell (it’s all because of their great use of aliases)

If you are so inclined, you can download each of the sessions to browse offline, or you can stream them from MVA.  Microsoft Virtual Academy also has a ton of courses on all kinds of Microsoft products and technologies.  You can also accumulate points and try and beat your friends at achieving some kind of status or something.  I don’t know – I tried that for a while but mostly I just want the content, not the points.

This is definitely share-worthy, so spread the word and help get your friends up to speed on PowerShell 3.

Learn PowerShell 3 in a Month of Lunches

Learn PowerShell 3 in a Month of Lunches

If you’re looking to expand your knowledge of PowerShell and start working it like a pro, you should check out this book from some of the premier PowerShell trainers and gurus.  Written by Don Jones and Jeff Hicks, Learn PowerShell 3 in a Month of Lunches takes you through the basics of PowerShell in a series of one hour training sessions. (These links take you to Amazon to buy the book. If you buy from these links, I’ll get a small commission but it won’t cost you any extra)

Each training session ends with a simple practice session to get you actually putting into practice the lesson of the day and turning it into some PowerShell code.

This is the second version of this book. But you don’t need the first, which was written for earlier versions of PowerShell.

If you’re wondering if you know enough about PowerShell to get started with Learn PowerShell 3 in a Month of Lunchesyou do. This first chapters and lessons start out just right for the person that’s wanting to learn PowerShell and it doesn’t assume that you have any knowledge coming in.

The later chapters guide you through some great techniques and principles that will help you to take your PowerShelling to new heights, both from an interactive shell and your written out scripts.

Don Jones is probably the most experienced PowerShell trainer out there.  He’s a multi-year recipient of the Microsoft MVP in PowerShell, and if you take a pre or post conference training session on PowerShell, it’s probably taught by Don. I’ve taken a training session from him before. I went into it thinking I knew a lot more than I actually did.  By the end of the training a couple of hours later, I had crazy new PowerShell-jitsu moves.

Jeff Hicks is a great PowerShell blogger, author and speaker.  He is also a Microsoft MVP for his work advocating PowerShell. He’s written training material for PowerShell and is an all-around cool guy.

I recommend this book as a great resource for getting up to speed with PowerShell.  We’ve been saying for years how important PowerShell is to system administrators, and if you’re ready to take the plunge this is an excellent way to start on the right foot.


PowerShell 3 Workflow Tutorial Video by Bruce Payette

This video features a PowerShell 3 workflow overview and tutorial from Bruce Payette.  Bruce is the Principal Developer in Windows Manageability for Microsoft.  This means that he is the main developer for PowerShell 3.0 and is one of the highest authorities on Windows management and scripting with PowerShell.

PowerShell 3 WorkFlow Tutorial

If you’ve heard that Power Shell 3 uses workflows, but you haven’t yet had an opportunity to learn about what it is and how to use it, this video is going to be time well spent.

It’s a ton on information packed into a 45 minute session from the PowerShell Deep Dive 2011 in Frankfurt.
Start the video when you’re ready to begin.  And if you just want the highlights then keep reading because I hit the key points for you.

What is Workflow and When Will You Use It?

Workflow is not another way to script, instead it’s orchestration of large, long-running scripts.  As Bruce puts it, workflow is intended for “reliably executing long running tasks.”

Workflows take advantage of state persistence:  everything in a workflow state can be saved to disk. The example given is a long running task finished processing one part of the script, and then human intervention is required. Once the human intervention is completed, the workflow can be resumed. If a system failure occurs on the machine running the workflow, it’s not going to affect the workflow. You can pick up and resume the workflow process on a different machine and it picks up right where it left off.

The main differences you’ll encounter when working with PowerShell workflows are:
• In a workflow, individual activities are isolated.  This is different than a typical power shell session or script where all of the activities take place more or less sequentially and all share the same environment and state.
Workflows include persistence, so that they are more robust.  This allows workflows to stop, pause, restart and recover.  Typical PowerShell scripting doesn’t include these state persistent features.
• Data flows through very specific channels when running through a workflow.  Everything is very well defined with data that comes in and data that goes out of each part of the workflow.  By contrast, scripts are allowed more flexibility with moving data from one part to another, and there can be “implicit” coupling of data.
Workflows are precise in how the language is typed.  A workflow is strongly typed, early bound, and is a compiled language.  Scripts can be more loose and forgiving with how the language is typed.
In short – workflows are planned, and scripts are ad hoc.

Overview of the PowerShell Workflow Architecture

There is a PowerShell Workflow Service (not a real windows service, unless you create a service to run the workflow).  The PowerShell workflow service is run on a computer which is actually running the workflow.  The client is the computer that is initiating the workflow.  The client and workflow service computers are usually the same computer, but could technically be two different computers.  Finally, the management nodes are the individual management items being processed by the workflow.  This could be as many computers as is required, and connections can be made through filesystems, WMI, and many other methods.
Example of a workflow code
Bruce showed this example of workflow code that checks for a required version of a system BIOS that will run on multiple machines.  It uses very little new programming syntax changes.  I typed in the code so that you can view it and copy paste it for your own education.

workflow Test-MachineBios
param ([parameter(mandatory=$true)][string]$RequiredBiosVersion )
parallel {
$workflow:bios = Get-CimInstance -ClassName Win32_Bios |
Foreach -MemberName Version

sequence {
$os = Get-CimInstance -Classname Win32_ComputerSystem
if ($os.Manufacturer -match “dell”) | { $workflow:RebootNeeded = $false }

inlinescript {

$bstr = “$bios”
$len = $bstr.Length + 15
“*” * $len + “`nBIOS version is $bstr`n” + “*” * $len | Write-Output

if ($bios -notmatch $RequiredBiosVersion) {
“Update Required”
if ($workflow:rebootNeeded -eq $true) {
“Reboot needed”
Restart-Computer -wait -for PowerShell -force
else {
“Reboot not needed”
else {
“BIOS is up to date”


Notes about the code:

  • If you want to create a workflow you start it with the workflow keyword. Once used, it enables some other new keywords.
    In a workflow, you can use parallel keyword to define tasks that run in isolation but at the same time. That is to say, each statement inside the parallel block runs on its own and at the same time on each system.
  • If you want to be sure to run one command first, and then another command after, you will want to use the sequence keyword. So even if you’re in a parallel block, the sequence block identifies a group of command that will be run one first, then the next; and that whole group of items being run in sequence will be processed in parallel with any other statements in the parallel group.
  • $workflow:bios shows a subset of the PowerShell language that only works in workflows. The data language makes it so you can only perform operations that make sense when working with data. Bruce puts it like this: “It prevents you from doing things that would prevent workflows from having the ability to persist.”
  • Since the things you can do in the data language is more restricted, you can use the inlinescript keyword to set aside a scriptblock that has the full PowerShell language available to it. Everything in the inlinescript block processes as one line in the workflow.

Other notes about this workflow, and designing and running workflows:

    If you restart your own computer, the workflow is saved by creating a checkpoint. After the computer restarts, you can resume the workflow.

  • As each step of the workflow is processed, progress bars are displayed by default throughout.
  • Commands now have a property called “capability” which identifies what type of command it is. Workflows are identified with the capability “workflow”.
  • Workflow commands are actually acting as proxies to the Microsoft Workflow version 4 engine.
  • The PowerShell text you enter into the PowerShell script is converted into XAML to be consumed by the the workflow engine.
  • It’s possible to edit the XAML directly, but not necessary and not recommended.
  • If you want to edit the XAML, using the workflow editor from Visual Studio is a good option.
  • You can do some basic debugging of workflows with Windows Tracing and Event logs.
  • Take advantage of tracing by loading the PSDiagnostics module, then running the Enable-PSWSManCombinedTrace command.
  • The Register-PSSessionConfiguration cmdlet can be used to help enable “second hop” connections by configuring remote endpoints to always be run as a specific user.

I can say that after watching this PowerShell tutorial I’m ready to start playing with workflows in PowerShell version 3.  I immediately started downloading and installing Visual Studio 2012 so I can get my hands on a decent workflow editor.
Do you know somebody that wants to learn one of the hottest new techniques for working with PowerShell?  Be sure to tell the people that need to know that you’ve got a really fast way to get them familiar with PowerShell workflows.


How to Find Enum Values in PowerShell


Windows PowerShell Cookbook Volume 3 by Lee Holmes


There are a couple of very easy ways to get a find enum values in PowerShell.  Enums are often used when choosing an option as a parameter in a PowerShell command.  This article shows you exactly how to get those values for any enumerated list type (called “enum”).

The easiest way to find enum values in PowerShell is to use Get-Help, but that doesn’t always work

The easiest way is by using the Get-Help command on a PowerShell cmdlet or function.  All of the built in PowerShell cmdlets have great help that is painstakingly created and maintained. Some of the functions that are included with PowerShell modules or a PSSnapin will also have documented parameters.

So the number one most simple way to check out the possible accepted values for an enum is to check with the get-help documentation.

It looks like this:

Get-Help Set-ExecutionPolicy –full


In the results, you can see in the values displayed inline with the parameter that accepts the type


Start by using Get-Help to try finding enum values. It is very fast, and the enum values are often in the help documentation.

That’s pretty good.  Unfortunately, the help for a function that was developed in house does not usually include such great documentation.

The best way to find enum values with PowerShell is to use a static method.

I’ll continue to use the Set-ExecutionPolicy cmdlet as my example, but these will work for any class that is an enum.

There are two approaches to this, and each one does the same thing.

First, you can use a static method from the base enum class, [system.enum].  Secondly, you can use a static method of the class (the enum) that you’re trying to identify the values for.

And before you can do either one, you need to identify the type that the enum represents.

How to find out the type of an enum

Consider the “Set-ExecutionPolicy” cmdlet, which uses a parameter “ExecutionPolicyScope” to specify at what level you want to apply the execution policy that you’re setting.

So if you want to know what options can go in

Set-ExecutionPolicy –ExecutionPolicy RemoteSigned –Scope  ???

You can find out what class the “Scope” parameter accepts by using Get-Help to interrogate the parameter.

Get-Help Set-ExecutionPolicy –Parameter Scope

Which returns just the information about the “Scope” parameter.



This shows that what you put into the Scope parameter is an object of type ExecutionPolicyScope.

That’s half the battle.  Actually, it’s way more than half the battle:  you’re almost done.

Finding out the names in an enumerated list (enum) when you know the type.

So now that we know the type, we need to be able to reference it.

To do this, I’m going to use a static method from the Enumeration class, SYSTEM.ENUM, called GetNames().  Use it like this:



And you will get all of the possible options for your enumerated list.  It might look like I took some liberties with the class name, because when it was listed in the Get-Help –Parameter output from above it was listed as “ExecutionPolicyScope” but when I entered it into the GetNames static method I used “Microsoft.PowerShell.ExecutionPolicy”.  When I first tried it with just “ExecutionPolicyScope” it returned an error.  So I made a guess that it was part of the standard PowerShell namespace, and it turned out to be correct.

By the way, the default PowerShell namespace is Microsoft.PowerShell and many PowerShell objects that are listed as only a class name actually belong to it, so it can be worth a try.

Many other enums listed as types in parameters for a command will list out the full namespace with the object.

Ok – so you’ve read the article.  I hope that you’ve gotten something great out of it.  I love helping people get more out of PowerShell, because I know PowerShell can help people do more work, faster, and with fewer mistakes than ever.

I’m committed to sharing great PowerShell advice and tips, so how’s about subscribing or spreading the word by sharing this article with a fellow that would benefit from it.

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.

Foreach ($day in $life) {Get-Knowledge | Export-AsSkill -Destination Brain}

%d bloggers like this: