Welcome to MSDN Blogs Sign in | Join | Help

SRV312 TechEd Slides

I just gave the talk, "”Server Management Improvements and Solutions for Windows Server 2008 R2”.  It went over rather well.  Attached are the slides.  I will try to get you the demos but that will be difficult and will take some time.

Enjoy!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Posted by PowerShellTeam | 6 Comments

Attachment(s): SRV312_Snover.pptx

Windows Server 2008 R2 Rocks!

One of the things I like to say is that, “Microsoft is incapable of sustained error”.  By that I mean that Microsoft is an intensely self-conscious culture, fearless about confronting shortcomings and  constantly looking for ways to do things better.  We beat ourselves up pretty brutally about the shortcomings of Vista and committed ourselves to doing better going forward.  This is one of the reasons why Windows Server 2008 was such a good release.  We didn’t stop there, we raised the bar for Windows 7 and Windows Server 2008 R2.

Part of that was the product itself.  Anyone that uses either of these products can see that immediately.  These are solid, high quality products.  We also raised the bar and teaching people about the release. 

This morning, MSDN’s Channel9 opened up a new site for learning about WS08/R2 HERE.  This site has lessons and short training videos for the following WS08/R2 topics:

Much of this content if focused on developers but admin/It Pro scripters will find PowerShell section useful and appropriate.

Experiment!  Enjoy!  Engage!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

PowerPack Challenge

Quest Software’s PowerPack Challenge’09 is on... calling all script warriors to show their skills.

See the details here - http://powergui.org/powerpackchallenge.jspa

Happy Scritping

Osama Sajid, Program Manager

Why is Get-ChildItem so Slow?

We get this question fairly frequently when it comes to slow network connections.

The performance of directory listings (especially on a laggy network) are limited by the .NET APIs we call to retrieve the directory information. There are two limitations to the current set of APIs:

Forced Retrieval of Attributes

When we do a directory listing, we show the standard attributes of the file or directory: Mode, LastWriteTime, Length, and Name. The core Windows API is highly optimized for this basic scenario, and returns these attributes by default along with the rest of the file information. However, the .NET Framework doesn’t take advantage of this data, and instead goes back to the network location to ask for all of the file attributes. This chatty behaviour adds a handful of network round trips for each file or directory, making the directory listing many times slower: hundreds or thousands of times slower in many cases. The Framework team addressed this as part of .NET 4.0, and you’ll see the benefits of this new feature as soon as we are able to adopt it.

In version two, even without the benefit of the new .NET API, though, you’ll see a huge improvement in wildcarded directory listings (both local and remote.)

As a background, PowerShell wildcards are different than straight cmd.exe wildcards. For example, PowerShell wildcards do not match the 8.3 short file name, while the native filesystem filtering (exposed by cmd.exe wildcards) do. PowerShell’s wildcards support character ranges, while the native file system filtering support does not. Because of this, PowerShell wildcard processing happens AFTER we’ve retrieved all of the files.

This comes at a cost, however. Native file system filtering (as exposed by the –Filter parameter) is MUCH faster, as its processing is wired into the Windows file system.

In version two, we did a bunch of work to resolve this strain. When you provide a PowerShell wildcard, we convert as much of it as possible to a native filesystem filter, and then apply our wildcarding logic to the much smaller set of results. You’ve probably noticed this most in tab completion, but it makes huge improvements in regular wildcarded directory listings. Especially remote ones. Since the native filtering is processed by the remote file system, we don’t need to suffer the performance penalty of accessing attributes of files that you ultimately don’t care about anyways. In version one, you can work around the issue by specifying the –Filter parameter directly. If this still doesn’t provide the speed you need, you can call “cmd.exe /c dir”.

 

Lack of Enumeration API

This issue raises itself for directory listings that contain many files. The DirectoryInfo.GetFiles() method returns an array. When creating that result list, the .NET Framework does many re-allocations (and copies) of that array, causing an exponential performance degradation:

GetChildItemPerf

 

This, too, has been resolved in the .NET 4.0 updates, by offering an API that lets you enumerate through a directory result, rather than retrieve them all at once. If you are running into these limitations, you can again apply a wildcarding approach. If this still doesn’t provide the speed you need, you can call “cmd.exe /c <command>”.

Why Don’t We Fix It?

Since cmd.exe isn’t impacted by these issues, why don’t we just do the same thing and call into the core Windows APIs directly? The reason is twofold:

  1. A core tenet of PowerShell is providing access to the REAL underlying .NET objects. If we implemented the semantics ourselves, we’d have to return new types of objects – something like PSFileInfo and PSDirectoryInfo. V1 scripts (or downstream cmdlets) that expect the REAL underlying .NET objects would fail to work. While we could add a new switch (-Raw?), users would still have to change their scripts to support it. In that case, they might as well use the existing cmd /c workaround.
  2. This issue is ultimately transient. While it’s annoying to drag out over a few years, it will ultimately come and go without users having to change their behaviour. One day, you’ll install a build and the issues will just magically be gone.

Again, thanks for your continuing feedback. That’s what ultimately helped us discover the issue and make sure the right people knew about it.

 

Lee Holmes [MSFT]
Windows PowerShell Development
Microsoft Corporation

Workaround for Add-Member on plain .Net objects

Introduction

While I was fixing bugs, I came across an interesting bug (https://connect.microsoft.com/PowerShell/feedback/ViewFeedback.aspx?FeedbackID=382818) that seemed to have a very simple fix upon first glance. However, after doing some more research, I found out that it was actually very tricky to fix the root cause. If you do the following:

$table = @{ key1="val1"; key2="val2" }
Add-Member -in $table -MemberType NoteProperty -Name test -Value testValue

Now if you pipe $table to Get-Member you will notice that the test property is missing. No matter how many times you repeat the same Add-Member operation, $table seems to be totally unaffected. However, if you access the test property or even a nonexistent property before you use Add-Member, the command will behave correctly.

Why is this happening?

In PowerShell, we create .Net objects as System.Object as opposed to System.Management.Automation.PSObject for performance reasons. This is because every time an object is converted from System.Object to PSObject, PowerShell has to build the metadata information by reflecting on the .Net object. Doing so can introduce unnecessary overhead since not all operations require PSObjects. When you do something with it (i.e. property access), it becomes a PSObject. However, when you pass a variable ($table) bound to an Object to a cmdlet such as Add-Member, the cmdlet internally converts the bound object into a PSObject. This effectively creates a copy of the original object and anything done to the PSObject is not reflected on the input object.

How can we work around it?

We are hoping to fix the root cause in the next release. However, the workaround is actually quite simple. Since Add-Member is able to emit the modified object if the –PassThru flag is specified, all you have to do is assigned the object back to your initial variable.

$table = Add-Member -in $table NoteProperty Test "Test property" –PassThru

Tianjie (James) Wei [MSFT]
Software Design Engineer
Windows PowerShell Team

Quick, Dirty, Super-Useful Scripting

Last weekend I installed the super-awesome W7 Ultimate on all the machines at home.  This weekend I decided to install the XP Virtual mode download.  I started to do this and noticed that it was 500MB.  That is large and is going to take a long time FOR EACH PC I have.  One of the reasons I got the Ultimate SKU is that it has BranchCache.  This is EXACTLY what Branchcache was designed to do.  One PC downloads something and puts it into a distributed cache and then when the other PCs go to download it, they get it from their peers instead of from the internet (given the way my son reacts when my downloads affects the network and  his ability to kill Nazi Zombies, I’m motivated to minimize the usage of the network :-) ).

That sounds great but the Branchcache is not enabled by default so you have to set it up.  I was doing this and it was a pain in the butt so I decided to experiment with a quick and dirty script and I LOVE the results so I thought I would share.

The issue is that they way you configure Branchcache is with NETSH.  The problem with that is that NETSH isn’t remotable.  I was going back and forth between machines trying things out.  I gave myself a dopeslap and I realized what I was doing and established a remote PowerShell session to the machines.  For a while I was doing Enter-PSSession which gives you an interactive session to the remote machine.  That was great but I have more than one machine so I either had to switch machines or have a couple of windows open.  Then I decided I would use Invoke-Command.  I created a remote connection to all the machines and then collected them in a variable $s and used ICM.

PS> $s = GSN
PS> icm $s {netsh branchcache show localcache}

That worked great but it was a little clumsy to work with so I decided to write a quick-n-dirty function to make my life better.

function b { icm $s -ScriptBlock $([scriptblock]::create("netsh branchcache $args "))}

Notice that I’m not using VERB-NOUN.  Why should I?  I’m after FAST (minimal typing) and this is a throw away function.  “B” is perfect.

Notice that I didn’t declare parameters.  Why should I?  I’m going quick.  I need it to work but I don’t need it to be formal.

Notice that I use positional parameters and aliases?  Why not? 

Now what I’m able to do is:

PS> b show localcache
PS> b set service mode=DISTRIBUTED

<UPDATE>
I realized from the comments that I didn't deliver the punchline.  The WHOLE point was that the command is going to run on ALL the machines!  THAT's the crazy wonderful part of it.
</UPDATE>

I haven’t got Branchcache working yet but I’m am zooming and having a blast.   We spend a lot of time talking about best practices and formal scripting.  That is all super great and super important but there is NOTHING wrong with quick-n-dirty scripting for adhoc functions.  The fact that we designed it so that you can do both with PowerShell is a source of great pride.

GOD I LOVE POWERSHELL!

Experiment!  Enjoy!  Engage!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Sending Automated emails with Send-MailMessage, ConvertTo-HTML, and the PowerShellPack’s TaskScheduler module

On October 15th I released a large collection of scripts called the PowerShellPack.  The PowerShellPack has tons of PowerShell V2 scripts that can be used to do all sorts of fun and practical things.  Today, we’ll show how to use a module in the PowerShell Pack to schedule sending a daily automated email with information about the installed programs on a given system.

Turning the output of a PowerShell script into an automated email is a snap in PowerShell V2, thanks to a nifty new cmdlet called Send-MailMessage.  Send-MailMessage sends out emails with the credentials of the current user (or an arbitrary user) and an SMTP server.  Send-MailMessage can send HTML emails by using the –BodyAsHtml switch, and ConvertTo-HTML can take the output of a cmdlet and turn it into an HTML chunk.  If the email needs some introduction and a signature, you can always use ConvertTo-HTML’s new –PreContent and –PostContent parameters.

Here’s a quick chunk of script that will send the email message once.  Notice that instead of having a very long line with a lot of parameters, I keep the parameters to Send-MailMessage in a Hashtable and use Splatting to provide them to Send-MailMessage

            $messageParameters = @{                        
                Subject = "Installed Program report for $env:ComputerName.$env:USERDNSDOMAIN - $((Get-Date).ToShortDateString())"                        
                Body = Get-WmiObject Win32_Product |                         
                    Select-Object Name, Version, Vendor |             
                    Sort-Object Name |             
                    ConvertTo-Html |                         
                    Out-String                        
                From = "Me@MyCompany.com"                        
                To = "Me@MyCompany.com"                        
                SmtpServer = "SmtpHost"                        
            }                        
            Send-MailMessage @messageParameters -BodyAsHtml                        

Now that we've got that chunk of code down, let's go ahead and make sure that any problems we encounter get put into a file somewhere.  I can do this by setting one of PowerShell’s magic variables $ErrorActionPreference = “Stop”, and adding a try/catch around all of my code:

        $ErrorActionPreference = "Stop"                        
        try {                        
            $messageParameters = @{                        
                Subject = "Installed Program report for $env:ComputerName.$env:USERDNSDOMAIN - $((Get-Date).ToShortDateString())"                        
                Body = Get-WmiObject Win32_Product |                         
                    Select-Object Name, Version, Vendor |             
                    Sort-Object Name |             
                    ConvertTo-Html |                         
                    Out-String                        
                From = "Me@MyCompany.com"                        
                To = "Me@MyCompany.com"                        
                SmtpServer = "SmtpHost"                        
            }                        
            Send-MailMessage @messageParameters -BodyAsHtml                        
        } catch {                        
            $_ |                         
                Out-File $env:TEMP\ProblemsSendingHotfixReport.log.txt -Append -Width 1000                        
        }

Finally, I’ll just go ahead and use the TaskScheduler module from PowerShellPack to make sure the email arrives every day.  To do this, I’ll need to download the PowerShellPack to the machine I’ll be scheduling the task on.   Scheduling a task with the PowerShell Pack involves a short pipeline:  Ours will look something like:

New-Task |            
    Add-TaskAction -Script {            
        # Our Emailer Here            
    } |            
    Add-TaskTrigger -Daily -At "9:00 AM" |             
    Add-TaskTrigger -OnRegistration |             
    Register-ScheduledTask "DailyHotfixReport"                

Piece of cake, right?  In our case, we’re sending an email at 9 AM every day (and when the task is registered) with the output of a simple cmdlet, but I could also use this to run a more complex task, and I can play around with the different trigger types to send the emails whenever I’d like.

Here’s the full script:

 

New-Task |                        
    Add-TaskAction -Hidden -Script {                        
        $ErrorActionPreference = "Stop"                        
        try {                        
            $messageParameters = @{                        
                Subject = "Installed Program report for $env:ComputerName.$env:USERDNSDOMAIN - $((Get-Date).ToShortDateString())"                        
                Body = Get-WmiObject Win32_Product |                         
                    Select-Object Name, Version, Vendor |             
                    Sort-Object Name |             
                    ConvertTo-Html |                         
                    Out-String                        
                From = "Me@MyCompany.com"                        
                To = "Me@MyCompany.com"                        
                SmtpServer = "SmtpHost"                        
            }                        
            Send-MailMessage @messageParameters -BodyAsHtml                        
        } catch {                        
            $_ |                         
                Out-File $env:TEMP\ProblemsSendingHotfixReport.log.txt -Append -Width 1000                        
        }                        
    } |            
    Add-TaskTrigger -Daily -At "9:00 AM" |                        
    Add-TaskTrigger -OnRegistration |                         
    Register-ScheduledTask "DailyHotfixReport"

That wasn't bad, was it?  It took only 24 lines of PowerShell script to create a schedule task that emails me a fairly detailed report of all of the installed programs on the machine. As you can see, PowerShell V2 makes sending automated emails a snap, and the PowerShellPack makes scheduling this or any other script on a regular basis a piece of cake.

Hope this Helps,

James Brundage [MSFT]

Windows Management Framework is here!

Windows Management Framework, which includes Windows PowerShell 2.0, WinRM 2.0, and BITS 4.0, was officially released to the world this morning. By providing a consistent management interface across the various flavors of Windows, we are making our platform that much more attractive to deploy. IT Professionals can now easily manage their Windows XP, Windows Server 2003, Windows Vista, Windows Server 2008, Windows 7, and Windows Server 2008 R2 machines through PowerShell remoting – that’s a huge win!

You can download the packages here: http://go.microsoft.com/fwlink/?LinkID=151321

 

Lee Holmes [MSFT]

Tonight is the Virtual Launch Party @ PowerScripting Podcast

Tonight is the night! 

I was super happy when we shipped V1 of PowerShell.  It started the journey.  That said, V2 is the release that we really wanted to release. 

Today Windows 7 is publicly available and every version has PowerShell V2 in it. 

Tonight – we party!

I’ll be cracking a beer with Hal Rottenberg and Jonathan Walz (hosts of the PowerScripting Podcast) in a PowerShell V2 Virtual Launch Party tonight at 9:30 PM EDT (GMT-4). 

For more details and info on how to join us go HERE.  I’m looking forward to seeing you.  Note, you can always watch the podcast after the fact but if you join, you can make comments and ask questions in the chat room – lots of fun.

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

PowerShell V2 Virtual Launch Party

I’ll be joining Hal Rottenberg and Jonathan Walz (hosts of the PowerScripting Podcast) in a PowerShell V2 Virtual Launch Party this Thursday, Oct 22nd, 9:30 PM EDT (GMT-4). 

For more details and info on how to join us go HERE.

Hmmm, I wonder if it is BYOB… :-)

Experiment!  Enjoy!  Engage!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Announcing: Open Source PowerShell Cmdlet and Help Designer

http://www.codeplex.com/CmdletDesigner

During the development of Windows 7, most cmdlet design and help authoring in Microsoft went through an internal tool called the “Cmdlet Designer.”

cmdlet_designerThe Cmdlet Designer makes it much easier for teams to concentrate on the design, naming, and consistency of their cmdlets, while also guaranteeing name registration and collision avoidance across Microsoft.

To sweeten the deal, it offers:

  • Integrated help authoring
  • Efficient bulk operations (parameter and cmdlet cloning)
  • Generation of cmdlet code
  • Full scripting support
  • Automatic code-spec comparison and testing
  • Role-based security, history logging, and more.

So why blog about it? Because it’s now yours!

We just posted the entirety of the Cmdlet Designer, its source code, design specification, and deployment guide to http://www.codeplex.com/CmdletDesigner under the most permissive Microsoft Open Source license, the Microsoft Public License (MS-PL).

Architecturally, the Cmdlet Designer offers a reference implementation to benefit developers as well:

  • UI on top of Cmdlets
  • Script-based UI extensibility
  • Cmdlet / Webservice interaction
  • Role-based security, with a trusted subsystem implementation

Download, and enjoy!

 

Lee Holmes [MSFT]
Windows PowerShell Development
Microsoft Corporation

Introducing the Windows 7 Resource Kit PowerShell Pack

Since I work on the PowerShell team, I’ve been lucky enough to get a couple of years jump start on producing PowerShell V2 scripts and modules.  With every new script I write in V2 I get more and more amazed by the possibilities in PowerShell.  I’ve discovered how to do many cool things that, as some of my colleagues outside of the PowerShell team have put it, have showed them the Power of PowerShell.

At each CTP of PowerShell, I’ve tried to share this power of PowerShell here on this blog.  Thanks to Mitch Tulloch (the main author of the Windows 7 Resource Kit) and Ed Wilson (the Scripting Guy), I was able to collect some of my V2 modules for the companion CD of the resource kit.  This collection of scripts became know as the Windows 7 Resource Kit PowerShell Pack.

Today, the Windows 7 Resource Kit should be available in stores, and the PowerShell Pack is available for download on code gallery.

The PowerShell Pack contains over 800 scripts in 10 different modules.  Here’s a brief overview:

WPK
Create rich user interfaces quick and easily from Windows PowerShell. Think HTA, but easy. Over 600 scripts to help you build quick user interfaces.  To get started learning how to write rich WPF UIs in script, check out Writing User Interfaces with WPK.

IsePack
Supercharge your scripting in the Integrated Scripting Environment with over 35 shortcuts.

TaskScheduler
List scheduled tasks, create or delete tasks

FileSystem
Monitor files and folders, check for duplicate files, and check disk space

DotNet
Explore loaded types, find commands that can work with a type, and explore how you can use PowerShell, DotNet and COM together

PSImageTools
Convert, rotate, scale, and crop images and get image metadata

PSRSS
Harness the FeedStore from PowerShell

PSSystemTools
Get Operating System or Hardware Information

PSUserTools
Get the users on a system, check for elevation, and start-processaadministrator

PSCodeGen
Generates PowerShell scripts, C# code, and P/Invoke

I’ll be posting a lot more about these modules in the next weeks, both here and on Channel9, but you can start exploring the modules now by checking out the PowerShellPack on code gallery.  I will also be tweeting some cool tidbits about the PowerShell Pack under the tags: #PowerShellPack, #WPK and #IsePack

I’ll also be on Hal Rotenberg’s PowerScripting Podcast tonight talking about the PowerShell Pack.

Hope this helps,

James Brundage [MSFT]

Quick Note: The MSI was updated at ~ 4:30pm on day of release. If you downloaded it before this time, please download the MSI again.

Posted by PowerShellTeam | 13 Comments
Filed under: , ,

Understanding the Feedback Process

During the development of any product, the vision for the upcoming release is driven by the desire to help as many customers in the most effective way possible.

One of the interesting aspects of a release is balancing the effort you spend on different aspects of that project:

  • New features and broad changes designed to address significantly new customer scenarios.
  • Feature updates and incremental changes designed to improve scenarios already (or partially) addressed by existing features.
  • Bug fixes designed to address functionality that doesn’t work as designed.

When weighing these factors, a critical factor is customer importance. Aggregate customer needs (and user research) heavily influence the first bucket, so the customer impact there is clear. The second two buckets come by way of direct customer feedback and bug submissions: http://connect.microsoft.com/powershell and pose a more difficult problem.

When looking at a piece of feedback in isolation, the customer impact is difficult to judge. While it is clear that the original feedback submitter ran into the problem, are they the only one to have run into it? Clearly, bugs and feedback that have broad customer impact are easy decisions to make when your goal is maximum value for the customer. Conversely, bugs and feedback that have little customer impact shouldn’t disrupt the features, feedback items, and bug fixes that do.

We’ve updated our Connect site to make this process as clear as possible:

clip_image002

If you are impacted by an issue, following those directions is the most constructive way to make your feedback known.

The key point here is that customer impact drives our decisions. You are the key for helping us determine customer impact. A vote for an existing bug or feature request is just as impactful (if not more!) than the original submission.

If you are impacted by an issue or have a suggestion, please visit http://connect.microsoft.com/PowerShell.


Lee Holmes [MSFT]

What's Up With Command Prefixes?

We like to say that PowerShell uses Verb-Noun naming.  If we were accurate, we would say that PowerShell uses Verb-PrefixNoun naming.  For instance: Get-WinEvent .  WIN is a prefix for Windows.  Every now and again people look at this and ask “what's up with command prefixes ?!?”.  Actually, the question usually comes from teams that are implementing Cmdlets and don't understand why they have to use prefixes.  They sometimes feel like their noun is unique or they want to own the noun or they think they may get reorganized into a different group so they are not sure what a good prefix would be (hey - is a legitimate issue for some teams – it just has nothing to do with the customer.)

Prefixes mitigate naming collisions. 

Consider the case of the recent cmdlet Get-WinEvent which was developed by the Windows Diagnostics team (the same great team that brought you the super awesome W7 troubleshooting [which uses PowerShell heavily]).  What would've happened if they'd just called it Get-Event.  The PowerShell team needed to use the name Get-Event Cmdlet (I'll explain why it doesn't use a prefix later) so without a prefix these two Cmdlet names would collide.  So what happens with a collision?  Well one wins and the other loses.  Specifically, last writer wins.  So if you had a script that uses Get-Event, it is going to use would ever last defined that name.  In other words your script will break. 

(NOTE: For the record – the story is much more complicated that that.  The Diag team used the name “Get-Event” first and we OKed it with them and then sometime later we got crisp about our policy for when PowerShell needs to own generic nouns and made them change it.  It was an unfortunate situation and the diag team ended up “taking one for the team” and doing a bunch of extra work so that we could deliver a great customer experience. We all owe them a big THANK YOU.)

No matter what we do, naming collisions will occur so let's talk about how you deal with that when it happens.  The solution is simple, you use the full Cmdlet name.  Full Cmdlet name?  Yes that's right, every Cmdlet that has a short and a full name.  The names you use all day long are the short Cmdlet names.  The full name Get-WinEvent is Microsoft.PowerShell.Commands.Diagnostics\Get-WinEvent.  That’s right, if anyone comes along and collides with Get-WinEvent, you just go change all your scripts to use Microsoft.PowerShell.Commands.Diagnostics\Get-WinEvent.  OUCH!  Clearly this is an undesirable situation but at the end of the day these things happen so you have to have a solution.  That said, it should be obvious why we want to avoid collisions as much as possible.

Think through the problem. 

  1. There are lots of things that need to be named.
  2. Everything has to have a universally unique name.  This either means a GUID or long human readable name.
    1. e2454d24-a4d9-4d41-b514-7b81f4257b64  vs. Microsoft.PowerShell.Commands.Diagnostics\Get-WinEvent
  3. You want to have short names and use them whenever possible.  In other words you want to avoid having collisions that require you to use the universally unique name.

When we thought through this problem we made some guesses about how many things needed to be named.  It's been many years since we had the discussion but I believe the numbers were something like this:

  1. We expected there'd be hundreds of thousands of Cmdlets in the industry.
  2. A large customer shop might have the 30-50 thousand Cmdlets running on all machines in their enterprise.
  3. Any particular machine might have 1-5 thousand Cmdlets on it.

The key observation here was that we had to minimize the possibility of short names colliding on a particular machine (not a customer site or the industry). 

Verb names are meant to be standard so they're always going to collide - that's a good thing (because it means you can guess which you want to do in your guess will be correct).  So this is really an issue of increasing the Hamming Distance of noun names.  Adding a 2-4 character prefix (indicating the team or product that owns the noun) in front of the noun solves this problem. 

  Chance of Collision
Without a prefix
Chance of Collision
With a prefix
Industry Absolute High
Large IT shop Very High Low
Machine High Very Low

 

NOTE:  The side benefit of using prefixes is that it provides an easy way to find all the commands from a particular source.  For instance, the Active Directory team chose the prefix “AD” so you can type:  Get-Command *-AD* to find all their Cmdlets.

 

So that is the reason why we are hardcore on the guidance to use prefixes in front of your noun names.

 

Oh wait, I promised to tell you why PowerShell sometimes doesn't use the prefix PS in its Cmdlets.  There are three reasons for this:

  1. Writing the code has its privileges.  :-) 
    1. Certain nouns are going to be used all the time and PowerShell is always there (by definition) so we used our unique position to grab some names to deliver a good user experience.
  2. We use generic noun names whenever we provide the framework for other people to plug into. 
    1. We used the name Get-Event because our eventing system is an extensible subsystem that anyone can plug into.  Get-Event then provides a common front end to all those plugins.  This is also the case for JOB, ITEM, etc
  3. We screwed up.
    1. In V2, we used the PS prefix a lot but I don’t think we were as consistent as we could have been.  Certainly this was the case for V1 where there are a number of cmdlets that should have used the PS prefix.  Live and learn.

But I hope this clarifies the importance of prefixing.  As a community it is in your best interest to enforce this standard quite getting grief to those teams and companies that don't adhere to it.

 

Enjoy!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Remoting for non-Admins

Per Østergaard has a great blog entry with all the steps for enabling this HERE.  You’ll want to bookmark this one.  :-)

 

Enjoy!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

More Posts Next page »
 
Page view tracker