January 26, 2010

You Can Do -Help
[Building HELP into your custom functions is a good thing! Here's a template to help you through it...]


Do you write your own Powershell functions for use in your AD or Exchange environment? Are they user friendly? Do others use them, or would you like them to? Do you add a -Help switch and display help text in your custom functions? You should! It's well worth your while to build in some HELP for a few reasons...

First, they won't be running to you to ask you syntactical questions even though you've told them six times already. Additionally, you won't be asking yourself those same questions when you try to use your awesome new function three weeks from now. Lastly, building inline help into your functions will force you to better understand how they work, as well as demonstrating your superior scripting abilities to your boss (make sure you demo the function at an upcoming staff meeting). Read on to see if your functions measure up.

Copy the code (link at end of post) and paste it into your Powershell session window to define the function called "MyTestFunction". To test the functionality, type the following at the Powershell prompt:

MyTestFunction (to show usage syntax)
MyTestFunction -Help (to display abbreviated help)
MyTestFunction -Help -Full (to display full help)
MyTestFunction SomeArgument (to simulate processing of SomeArgument)



Notes and Code for this post:
Get the shell function code here.
Although the copy code & "paste into your Powershell session" method of defining the function works for testing the function, the content should really be copied and pasted into an editor such as notepad.exe, then saved as a .ps1 script. This will retain the HELP text formatting (blank lines) that get stripped out when copy/paste into session window is used. Try it, you'll see what i mean.

This code works with Powershell v1 and v2.

Was there enough detail in this post?




.end


more...

January 14, 2010

Script Output - Formatting with -f
[Align your columns the way YOU want]

This article will discuss absolute positioning of Powershell screen output. There are times when the standard formatting of Powershell output just won't cut it. Enter the -f formatting operator. Until you get familiar with its syntax, the use of this operator can be somewhat cryptic. In the following discussion, I'll attempt to shed light on the many options available and show how we use it for output formatting.

Consider the following code:

$All_MBXs = Get-Mailbox
foreach ($MBX in $All_MBXs) {write-host $MBX.Name,`

$MBX.PrimarySmtpAddress}


and the resulting output:


If we replace the write-host cmdlet using the -f output formatting operator, we can produce the following output:

The code change to produce the output above is shown below. Note that the Write-Host cmdlet is completely replace with the -f operator construct.

$All_MBXs = Get-Mailbox
foreach ($MBX in $All_MBXs) {"{0,-14} {1,-25}" -f `
$MBX.Name, $MBX.PrimarySmtpAddress}


In looking at the code in the example above, we use {} to encapsulate the formatting specifiers, then -f to indicate the start of data items to format.


Formatting Details Explained

"{0,-14} {1,-25}"


The first set of curly braces {} define what data to display and the column padding to use for it. In this example, data object zero, $MBX.Name (the first item defined by the object's position as it appears after the -f ) will be output with a column width of 14 . The minus sign preceeding the column width of 14 indicates that the data should be "left" justified... leaving it off will "right" justify that piece of data when output. [Note: Using a plus sign rather than no sign will produce an error in your script].


What we are building is a formatting template (note parenthesis surrounding the entire "template") that will be used by the -f operator when it decides how to display the ouput. Also worth mentioning here is that the space between the two sets of braces IS relevant. For example, if you insert ten spaces between the two sets of braces, the -f operator will interpret that as space that you want to show in the output.


The second set of curly braces in the example indicate that data object one (the second item in the list after the -f) will be output with a column width of 25, right justified.


The use of the -f operator to product custom output is a powerful and relatively easy tool to produce great looking and easily readable output. There are several other formatting options using this method, such as percent and currency specifiers, numeric formatting, partial date/time specifiers for hours, minutes, days, etc. I won't go into those now, but may in the future post.


The best way to learn this formatting option is to play with some code and see how it affects your output. Enjoy and happy scripting!

.end


more...

January 13, 2010

A Customized Get-Mailbox... and more.

I like to make things easy for myself when possible. That being said, I also spend a good amount of time writing scripts that will help with that. Therein lies the rub. Is it worth my while to spend hours getting a script just right? The short answer, Yes I think it is. The somewhat longer answer and reasons behind it, is a topic for another day.

Often when I'm troubleshooting user issues, I'll need to get the user's mailbox information, usage statistics, and frequently their OWA settings. Getting this information from the Exchange Management Shell will require me to enter three cmdlets (once I figure out what the user's alias is). I can never remember to use the -ResultSize Unlimited switch until it's too late, nor can I remember to use the -ANR (Alternative Name Resolution) switch so I can search for FirstName, LastName, Alias, PrimarySMTPAddress, etc.

My solution... write a script that calls Get-Mailbox with the -ResultSize and -ANR switches built into it. But why stop there? The script will prompt for which of the 19 Michaels the search returned, then display full Get-Mailbox, Get-CASMailbox, and Get-MailboxStatistics information for the requested user. Now I have all the information I typically need to troubleshoot a user problem.

Are we finished? Nope. Why not turn this script into a function and load it in our Powershell $Profile so there is no need to dot source it? Sure, now we can run it no matter what our current directory is. Now we're talkin' right?... or are we? The problem now is... I'm not the only Exchange Admin in my group, and what if he thinks my script is cool and wants to use it? Ah... but we can handle that too! Yes indeed, instead of loading the function in Powershell's personal profile (see Understanding Powershell Profiles), we can add it to the machine profile instead. Now any user that logs onto the box and runs Powershell will have the function pre-loaded and available for use during their session.

The Home Stretch
This is all good stuff, and is working like a charm. We get to thinking about this a little more and realize... "Hey, I can only use this awesome new script on the server that I'm logged onto." Not really a problem as the script can access information from other machines. However, what if my buddy Bryan wants to use the script but he's logged onto one of the Hub/CAS servers and the script lives on the Mailbox Cluster? Several options here. The one we have been using is...

...you guessed it, another script! This script is just a simple file copy script to distribute the machine profile to the other Exchange servers in our environment. The script will check the current server and will, after getting confirmation from the user, copy the local machine profile to the other Exchange servers. This works well for us and provides a consistent environment while working in Powershell on any of our Exchange servers.

Note: For those of you who are running Exchange 2007 SP2, you can install Powershell v2, which gives you the import-module cmdlet, allowing you to locate your functions on a network drive and load them from a share. Change the function in one spot, and all of your servers are up to date at the next Powershell session login. Don't forget to name the file you store your functions in with a .ps1 extension, the import-module cmdlet won't allow .txt extensions.


.end

more...

August 21, 2009

What's your favorite PICKUP line?
[C'mon, everyone has one, so fess up!]

Ours (at least in the office) is:
copy serverstatus.eml \\myTransportServer\Pickup

Do you have a need for an easy method of sending a message from within your Powershell scripts? Do your automated procedures report their results to you via email? Do you want them to? Details? Summaries? Have you used the pickup folder to send messages from your monitoring or mailbox processing scripts? If not, you should be. Read on to see how easy the process can be, especially for you Exchange Admins.

Here at ITEC, we host mailboxes for a few campuses and SUNY entities. Automating procedures helps us to provide consistent, and faster service to our customers. Scripting as many procedures as possible helps in standardization and minimizes the chance for error. However, automated processes can sometimes go on without monitoring and without an administrative eye watching over them. Notification from these automated procedures is sometimes critical to system health as well as customer satisfaction. An easy way to use your Exchange environment to deliver status messages and reports is to use the PICKUP folder on your Exchange Transport server.

First, we should create a share that points to the pickup folder on one of your transport servers to use as your drop folder for system status messages.


Format your message following RFC-822 standards as shown below, naming it with an .eml extension, then copy it to the pickup share to be delivered by the Exchange transport server. We use a Powershell function (discussed later in this article) that we've written to make our mailer procedure transportable, but you can easily put the code inline in your reporting script.

From:
To:
S
ubject:

Message body here. (Content from your report file)


Make sure there is a blank line between the Subject: line and the start of your message body... that's all there is to it. Exchange monitors the pickup folder for new messages and processes them as long as they are formatted correctly. We use a script to build the output file with very simple Powershell write-output cmdlets.


Building the email message takes no more than the few Powershell lines shown below. After the output .eml message file is created, it's simply a matter of copying the file to the pickup share for processing.


$Msg = "MyMessage.eml"
$MsgBody = Get-Content C:\temp\MyReport.txt
$MsgDisclaimer = "Some company mumbo jumbo..."
write-output "From: $fromaddr" out-file $Msg -encoding ASCII
write-output "To: $toaddr" out-file $Msg -encoding ASCII -append
write-output "Subject: $subj" out-file $Msg -encoding ASCII -append
write-output "`r`n" out-file $Msg -encoding ASCII -append
write-output " -Automated Msg -" out-file $Msg -encoding ASCII -append
write-output $MsgBody out-file $Msg -encoding ASCII -append
write-output $MsgDisclaimer out-file $Msg -encoding ASCII -append
Move-Item $Msg -destination \\MyTransportServer\PickupShare\


Using a function to build and send the message makes calling the mailer easier and allows us to use it in many different procedures. Our version of the function (to be discussed in a future post see Note below) includes detailed help as we anticipate the function being used by several staff from within many different scripts.




Note: The post to discuss ITEC's custom function for sending using the PICKUP folder will be replaced by a post about the Powershell v2 cmdlet Send-MailMessage, which we will discuss instead.


.end

more...

July 1, 2009

OWA Session Timeout Ticking You Off?

Are your users complaining about the short session timeout for Exchange 2007 Outlook Web Access? OWA users who have selected the "This is a private computer" login option either from home or at the office are subject to the default 10 minute session timeout. Use this easy fix to increase the value to something more acceptable to your users (if your local security policy allows it) say... 8 hours?

As you may know, Powershell can access the Registry directly, just as it can access the file system. There are two predefined psdrives available when you load Powershell that point to the Registry hives HKEY_LOCAL_MACHINE (HKLM) and HKEY_CURRENT_USER (HKCU). You can add others if you choose by configuring your Powershell user or machine profile.

To use Powershell to add (or change) an entry in the registry to increase the OWA session timeout for "trusted" clients to 8 hours (480 minutes), use the Exchange Management Shell and type the following command or use Regedit: (the usual warnings apply)

New-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\MSExchange OWA' -Name TrustedClientTimeout -Value 480 -Type dword

Restart IIS from a command prompt using iisreset /noforce and your users will love you.

.end

more...

June 18, 2009

Confluence Automation with Powershell
[aka Scripting your Wiki - Part I of a series]

For those of you who use the Confluence wiki to maintain documentation, this post will show you how we at ITEC use Powershell scripting to automate reports and build pages using the Confluence Command Line Interface (CLI). The Confluence CLI is a Java based set of procedures for automatically creating/updating pages in your Confluence spaces.

We have several systems that report their status to various tools that generate reports for internal staff. Read on for details on how we use Powershell and the Confluence CLI to automate documentation for internal system status reporting as well as usage statistics for campus applications that we host.

How We Use It
Responsible for managing and maintaining our Exchange environment as well as our hosted mailboxes, I am always looking for ways to streamline procedures and to minimize the chances of human error through automation. The discussion that follows shows a detailed example of how we use both Powershell and Confluence to produce high quality, accurate, and timely system status information for our campus customers.

Exchange Mailbox Status Reporting
The goal here is to provide our campus customers easily accessible, up-to-date information on the status of their mailboxes. Information such as current mailbox sizes per user, mailbox forwarding, time of last logon, etc.

to be continued...

more...

June 13, 2009

Understanding Powershell Profiles


Powershell uses profiles to configure the user experience. There are two main profiles that are typically configured, the machine profile and the user's personal profile.

MSDN has a nice description of the different profiles found in Powershell. You can pre-define variables, drive mappings, custom functions, etc. Shared routines can be loaded into the machine profile to provide access to ANY Powershell user on the system.

The machine profile is found at
%windir%\system32\WindowsPowerShell\v1.0\profile.ps1
and is used to configure the Powershell session for ALL users on the system. I generally use the machine profile to define custom functions that should be available to anyone who logs onto the box and will use Powershell. Examples could include writing a custom function and add it to the machine profile on a domain controller that would open a csv file or make a database connection, read its data, and create a new AD user, configure a home directory on a file share for that user, and add them to the appropriate security groups.

Another example would be writing a function that lives in the machine profile of an Exchange server, available to ALL admins who log onto the machine. I have a custom script that I've turned into a Powershell function for planned failover of our clustered mailbox servers. The script (function) takes input from the admin, verifies that the target node is not already the active node, displays the status of the cluster copy queue, then warns the admin that this procedure will failover the production mailbox cluster. No browsing folders searching for the location of the failover script... when it's defined as a function, it's available from any location.

The user personal profile is found at
%UserProfile%\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
and is used to configure the user's personal settings. Screen color preferences, personal drive mappings (psdrives) , and functions that should not be made public on that system. Security Credential Objects that will be used within the Powershell session can also be defined here.

You can edit this profile with any standard text editor such as Notepad, but there are many IDE applications available to make script editing easier. Powershell 2.0 includes a builtin IDE.



Notes for this post
Get a quick reference here.

.end

more...