Guy’s Scripting Ezine 111 – Profile.ps1 and Cmdlets

Guy’s Scripting Ezine 111 – Profile.ps1 and Cmdlets


This Week’s Secret

I had a misspent youth playing with AutoExec.bat and Config.sys.  Thus I was familiar with files such as profile.ps1, which control PowerShell’s startup environment.  Nevertheless, I fell into the trap of calling the file profileS.ps1 instead of profile.ps1.  The lesson is PowerShell consistently uses singular nouns.  Learn from my mistake and remember that it’s profile, process and service and not profiles, processes and services.

This Week’s Mission

This Week’s Mission is to persuade PowerShell to read script files.  This is an easy task because all you need to do is save regular commands into a file with .ps1 extension.  Then you call your file, known as a cmdlet, from the PowerShell command line.  However, I would like to start with the special file called profile.ps1 and then move on to cmdlets.

Profile.ps1 is a special cmdlet.  The only tricky part is creating profile.ps1 in the correct location.  It is a mystery to me why the PowerShell_Setup-i386.msi does not create the PSConfiguration folder and the profiles.ps1 file automatically.

1) Enabling cmdlets (Scripts) in the Registry

Without making the following registry hack you may get an error message:  ‘The execution of scripts is disabled’.  What I did was to change a REG_SZ called ExecutionPolicy from Restricted to UNRestricted.  Here is the full path to enable .PowerShell cmdlets in general and profile.ps1 in particular.

HKLM\Software\Microsoft\PowerShell\1\ShellIds \Microsoft.Management.Automation.PowerShell

Alternatively, use PowerShell’s own commands to manipulate the registry:
set-ExecutionPolicy Unrestricted. 

Investigate other settings such as RemoteSigned, try typing set-ExecutionPolicy -?

See more about the PowerShell set-ExecutionPolicy command

2) Locating the path for the Profile.ps1 file

My main problem was locating the precise path shown below.  In truth, it was my fault for not paying attention to detail, I was too busy being annoyed that the installation did not create the PSConfiguration sub folder, that I kept creating PSConfiguration in slightly the wrong place.  Note: as with all PowerShell nouns, profile.ps1 is the singular.

See here for the latest on Profile.ps1

C:\Documents and Settings\All Users\Documents\PSConfiguration\profile.ps1

Preparation:  Navigate to your Windows directory called, ‘All Users’, then find either of these sub folders.

C:\Documents and Settings\All Users\Documents\
C:\Documents and Settings\All Users\Shared Documents\

First Task: Create a sub folder called precisely PSConfiguration for example
C:\Documents and Settings\All Users\Documents\PSConfiguration

Second Task:  Launch notepad and create a file called precisely profile.ps1.  Make sure that you have the correct file extension, .ps1 and not txt or even PowerShell.txt.  This is the position, you should now have:

C:\Documents and Settings\All Users\Documents\PSConfiguration\profile.ps1PowerShell Command Line

Third Task:  In profile.ps1 just add an instruction to clear the screen.  I confess that I used cls to mask error messages about the phantom "P:\" drive.  On the next line I added a phrase to prove that it’s my profile.ps1 which is active and not the default profile.ps1.
"Guy was here "

Fourth Task:  Now launch PowerShell.

Once you have succeeded in placing your profile.ps1 in the correct path then you can read up about flashy commands to enter into this startup configuration file, profile.ps1.

Guy Recommends: The Free IP Address Tracker (IPAT) IP Tracker

Calculating IP Address ranges is a black art, which many network managers solve by creating custom Excel spreadsheets.  IPAT cracks this problem of allocating IP addresses in networks in two ways:

For Mr Organized there is a nifty subnet calculator, you enter the network address and the subnet mask, then IPAT works out the usable addresses and their ranges. 

For Mr Lazy IPAT discovers and then displays the IP addresses of existing computers. Download the Free IP Address Tracker

2b) Profile.ps1 Plan B Location

In addition to ‘All Users’ PowerShell looks for profile.ps1 in an alternative location.  That place is the %username%, in my case this translates to GUYT.

C:\Documents and Settings\GUYT\Documents\PSConfiguration\profile.ps1

The only reason that I did not mention this before is that there can be no mistake with the ‘All Users’ folder, whereas making the translation between %username% and the equivalent name under \Documents and Settings, means losing 15% of readers.

Another example of profile.ps1

"Welcome to PowerShell, " + $env:Username
set-location d:\scripts

3) PowerShell Cmdlets

Filename and .ps1 extension

When you create the cmdlet with notepad, the filename must have a .ps1 extension for example, RunningProcess.ps1.  To create such a file, save your PowerShell commands in notepad, then from the file menu: Save As, Type, All Files, RunningProcess.ps1.  Just to be doubly sure, you could put the filename in double quotes "RunningProcess.ps1".  I maybe paranoid, but please check the file is not called RunningProcess.txt or RunningProcess.ps1.txt.

What you put in filename.ps1 are the same commands that you type in the Microsoft Shell.  You could start with a simple verb-noun pair, for example just:


Here is a more advanced set of instructions just to give you the idea of the power of the cmdlets.


# RunningServices.ps1
# This script generates a report about Running Services
# Guy Thomas May 2006

# Version 1.5

"" # Insert a blank line

"Report generated at " + (get-date)
""  # Insert blank line

"Services that are running"
get-service | where-object { $_.status -eq "Running"}


Learning Points

Note 1: The key command in this example is get-service.  Note the singular noun.

Note 2: Observe the where clause. $_.status is one of the process columns.   -eq means equals the value in quotes: "Running" in this example.

2b) Calling the filename

Assumptions: You saved the cmdlet script files into a directory called D:\ scripts.  Also the actual file is called RunningServices.ps1.

When you execute the cmdlet by calling the filename from the PowerShell command line, you don’t need to add the .ps1 extension.  However, you need to pay attention to the path. Start with the full path e.g. D:\ scripts\RunningServices.

When that works, build on success, navigate in PowerShell to the D:\ scripts folder with
set-location d:\ scripts
Now issue the shorter command: .\RunningServices 

Note: Observe the dot and the slash in front of the filename, incidentally the slash can be either backslash or forward slash, therefore, ./runningservices works.

Guy Recommends: Tools4ever’s UMRAUMRA The User Management Resource Administrator

Tired of writing scripts? The User Management Resource Administrator solution by Tools4ever offers an alternative to time-consuming manual processes.

It features 100% auto provisioning, Helpdesk Delegation, Connectors to more than 130 systems/applications, Workflow Management, Self Service and many other benefits. Click on the link for more information onUMRA.

Summary of PowerShell and Cmdlets

This week I have two goals, my first goal is to control PowerShell’s startup environment with profile.ps1.  My second goal is to show you how to create cmdlets.  These script files have normal files saved with .ps1 extension.  You can then call the cmdlet from the PowerShell command line.

If you like this page then please share it with your friends


See more Microsoft PowerShell tutorials

PowerShell Tutorials  • Methods  • Cmdlets  • PS Snapin  • Profile.ps1  • Exchange 2007

Command & Expression Mode  • PowerShell pipeline (|)  • PowerShell ‘where‘  • PowerShell ‘Sort’

Windows PowerShell Modules  • Import-Module  • PowerShell Module Directory 

If you see an error of any kind, do let me know.  Please report any factual mistakes, grammatical errors or broken links.