QuickStart PowerShell Remoting

Just created a new Wiki page on the PowerShell Survival Guide that is a quick guide to getting started with PowerShell remoting. I focused strictly on PSSession, since I find that the simplest way to get started. Let me know what you think, or better yet, update the content to improve it. That, after all, is what a Wiki is all about!

Blog Retirement

I and several Microsoft employees and other MVPs started this blog many years ago, at the dawn of the Microsoft x64 era, with the intent of providing a place to find solutions and information around 64-bit Windows computing. And, over the years, I think we did a good job of providing a place for those solutions that the community discovered to reside. After the initial flurry of activity, the rest of the folks who were part of that original group pretty much dropped off, and it became my personal blog, while still trying to stay a bit focused around 64-bit computing. But the reality is that 64-bit is here, and it’s now mainstream. Time for this to retire, and my blogging to move to be more focused on the new things that I am working on and with. So, from here on out, you can find me at my new blog. There I’ll be discussing PowerShell (I am a PowerShell MVP, after all), Windows Server in general, and Windows Small Business Server in its various editions as well. A lot of that Server focus will be around the technology that I live with every day—virtualization. Both machine virtualization (Hyper-V), and application/session virtualization (RemoteApps, Remote Desktop Services, and VDI.) So come on over and say “Hi”.


Thank you,


Charlie Russel

Microsoft MVP since 2000.

Customizing PowerShell–Using $Profile

Probably one of the first scripts any new Windows PowerShell user writes is a custom profile. Your PowerShell profile ($profile in PowerShell speak), is run every time you open a PowerShell window, and it allows you to do a lot of different things to set up your environment the way you want it. Actually, though, there are four profiles that affect your PowerShell window, as described in this MSDN article. There are arguments for which profile you should be editing, but my personal preference is to use the most specific one:

%UserProfile%\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

The only problem is, that’s not really were “My Documents” is for me. So, how to be sure you always work on the right one, wherever it’s located? Easy – let PowerShell tell you!

First, let’s see if we have a $profile yet:

PS1> Test-Path $profile

Nope. So, how to make one. First, let’s create the path:

PS1> mkdir (Split-Path $profile)

    Directory: C:\Users\cpr\Documents

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        12/22/2010  12:05 PM            WindowsPowerShell

Now, use your favourite plain text editor to create the file. In my case that would be:

PS1> gvim $profile

And here you can start to build your customizations for PowerShell. There are lots of possibilities, including changing the colouring, updating the title bar, creating aliases and functions that are always available. Really the possibilities are nearly endless.

In my own case, I like to distinguish between a regular window and an elevated one, so I change the colour of all my regular PowerShell windows to white with dark blue text (works better for screen shots), and my elevated windows to dark red with white text. I also use a multiline prompt, and do some other customizations.

Here’s my full $profile:

# This is Charlie's custom PS Profile...
# ModHist: 26/05/2007 - Initial
#        : 08/06/2007 - Added clear-host and winzip alias
#        : 10/06/2007 - Changed OS detection
#        : 22/07/2007 - support for running from local home
#        : 14/03/2008 - changed to Microsoft.PowerShell_profile.ps1 and fixed Server 2008 switch statement
#        : 16/03/2008 - added productID test for Vista
#        : 24/03/2009 - added mapdrives for admin shell
#        : 17/10/2010 - minor cleanup before sending to VanTUG

# Get the name of this version...
$CallingProfile = $myInvocation.mycommand.path
$FileRegEx = "(?<name>.*)(?<dot>\.)(?<extension>[pP][sS]1)"
$CallingProfile -match $FileRegEx

# Find out who we are...
$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$p = New-Object system.security.principal.windowsprincipal($id)

# Get System WMI info -- Get it once, use it multiple
$SysWMI =  Get-WmiObject Win32_OperatingSystem
$hostname = $(hostname).tolower()
$otherway = ($ENV:computername).tolower()

$ProductID=(get-item 'HKLM:/Software/Microsoft/Windows NT/CurrentVersion').getvalue('ProductID')

# Build a hashtable with information about versions, etc.
$SystemHash = @{}  # Initialize the variable as a hashtable
$SystemHash["Build"] = $SysWMI.BuildNumber
$SystemHash["SPNumber"] = $SysWMI.CSDVersion
$SystemHash["Caption"] = $SysWMI.Caption
$SystemHash["SKU"] = $SysWMI.OperatingSystemSKU
$SystemHash["Architecture"] = $SysWMI.OSArchitecture
$SystemHash["Hostname"] = $SysWMI.CSName.ToLower()
#$SystemHash["Arch"] = $ENV:Processor_Architecture # redundant, already getting from WMI

# We’ll need the build number to persist in the environment
$Build = $SystemHash["Build"]

switch -regex ($SystemHash["Build"]) {
   2600 { $ver="XP" }
   3790 { if ($SystemHash["Caption"] -match "XP") {
            $ver = "XPx64"
         } else {
            $ver = "Server 2003"
   6000 { $ver="Vista" }
   6001 { if ($SystemHash["Caption"] -match "Vista" ) {
         } else {
            $ver="Server 2008"
   7600 { if ($SystemHash["Caption"] -match "Windows 7" ) {
      $ver="Windows 7"
      } else {
      $ver="Server 2008 R2"
   7601 { if ($SystemHash["Caption"] -match "Windows 7" ) {
      $ver="Windows 7 SP1"
      } else {
      $ver="Server 2008 R2 SP1"

if ($SystemHash["Arch"] -eq "AMD64" ) {
} else

# Find out if we're running as admin (IsInRole)
# if we are, change the window colour and set effectivename variable
# But only on Windows Vista or Longhorn Server
if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) -and ( $build -ge 6000 )) {
      $effectivename = "Administrator"
      $maps='C:\Windows\system32\mapdrives.cmd'  #cmd file to map standard drives
      if (Test-Path $maps) {& $maps }
   } else {
      $effectivename = $id.name

$host.ui.rawui.WindowTitle = $effectivename + "@" + $HostName +" >"
function global:prompt {
   if ( $effectivename -eq "Administrator" ) {
      write-host ("[") -nonewline -foregroundcolor red
      write-host ($Hostname) -nonewline -foregroundcolor Magenta
      write-host ("]") -nonewline -foregroundcolor Red
      Write-Host ([string]$(get-location) +":") -foregroundcolor Green
      write-host ("PSH>" ) -nonewline -foregroundcolor White
    } else {
      write-host ("[") -nonewline -foregroundcolor red
      write-host ($Hostname) -nonewline -ForegroundColor Magenta
      write-host ("]") -nonewline -foregroundcolor Red
      Write-Host ([string]$(get-location) + '> ') -ForegroundColor DarkGreen
      write-host ("PSH>" ) -nonewline -foregroundcolor DarkBlue
   return " "

# function to elevate a command. Finally.
function sudo ([string]$file, [string]$arguments) {
    $psi = new-object System.Diagnostics.ProcessStartInfo $file;
    $psi.Arguments = $arguments;
    $psi.Verb = "runas";
    $psi.WorkingDirectory = get-location;

# Now, a function to edit the executable script without knowing where it is.
function fvi
   param($script )
   $s = (get-command -ea silentlycontinue $script).definition
   if ( $s ) { gvim $s }
   else { "$script not found" }

# Update the path to make life easier, and add a function while we're at it...
$ENV:Path="$ENV:PATH;" + "U:\psbin;" + "$ENV:HOMEDRIVE" + "$ENV:HOMEPATH" + "\psbin"
function path {
   write-host $env:path

# Now, start to build some aliases. These may be machine specific, so be careful...

if ($64bit) {
set-alias winzip -value "C:\Program Files (x86)\WinZip\WinZip32.exe"
set-alias word -value "C:\Program Files (x86)\Microsoft Office\Office14\WinWord.exe"
set-alias excel -value "C:\Program Files (x86)\Microsoft Office\Office14\Excel.exe"
set-alias OneNote -value "C:\Program Files (x86)\Microsoft Office\Office14\OneNote.exe"
set-alias Visio -value "& mstsc C:\Program Files (x86)\RemotePackages\Visio_2010.rdp"
set-alias hyperv -value "C:\Program Files\Hyper-V\virtmgmt.msc"
set-alias vm -value "C:\Program Files\Hyper-V\vmconnect.exe"
} else {
set-alias winzip -value "C:\Program Files\WinZip\WinZip32.exe"
set-alias word -value "C:\Program Files\Microsoft Office\Office14\WinWord.exe"
set-alias excel -value "C:\Program Files\Microsoft Office\Office14\Excel.exe"
set-alias OneNote -value "C:\Program Files\Microsoft Office\Office14\OneNote.exe"
set-alias Visio -value "& mstsc C:\Program Files\RemotePackages\Visio_2010.rdp"

set-alias edit -value "C:\Windows\gvim.bat"
set-alias vi -value "C:\windows\gvim.bat"

# set-alias ping test-connection # disabled. More annoying than useful

# The following is useful if you have automatic startup PowerShell windows...
if ( $effectivename -ne "Administrator" ) {
   cd $home

There, that’s complicated enough for most uses. 🙂 But hopefully you’ll find some useful stuff in this that you can use for your own $profile.



Recovering an HP Disk Array

As I reported earlier, my HP ML350 G5 died, and it was clearly a motherboard failure. Now that was bad enough, but worse was that I had VHD files on the P400 RAID5 array that were not as recently backed up as was desirable. Given that the ML350 wouldn’t boot at all, how to recover the important information on the array?

Well, thanks to a suggestion from Greg Starks, a friend at HP, I was able to completely and easily recover all the content of that array. The key requirement was to have a second machine that supported a similar HP RAID controller. And, by the way, it looks highly probable that the original RAID controller will be usable in a non-HP machine. But I digress.

I have an HP DL160SE G6 rack mount server here as well. Now it has a similar, though not identical, RAID controller built in to the motherboard. So, here’s what I did to get the files off the RAID array from the failed server:

  1. Built a USB pen drive with a bootable Windows Server 2008 R2 installation image on it. (The DL160SE doesn’t have an optical drive in it at all.)
  2. Removed each of the drives from the failed server, carefully marking each one with a piece of masking tape so I knew which slot they came out of.
  3. Removed each of the drives from the DL160, again marking the drives carefully with masking tape.
  4. Plugged the drives from the failed server in the exact same order and slot number. (These were all 2.5” SFF SAS drives, though the procedure is the same regardless.)
  5. Booted from the USB pen drive, and also plugged in a 1 TB external USB drive.
  6. Selected Recover at the initial boot screen for the Server 2008 R2 setup. This allowed me to get to a command prompt.
  7. At the command prompt, used
      RoboCopy <sourcedrive> <targetUSBdrive> /mir
    to copy the contents of the failed array onto the external USB drive. (Be patient, USB2 is slow.)
  8. Shutdown the HP160, and returned the original drives into their original slots. Removed all USB drives from the HP160 and booted normally.

Now, I had all the data files from the failed server on my 1TB USB disk, and I can put them anywhere.

What’s important to understand about this procedure is that it worked even though my array didn’t have any boot information on it. By making a boot USB stick, I could boot to that and suck off the files. And because the HP P400 RAID array drivers are built in to the Windows Server 2008 R2 installation image, the whole thing was completely painless and transparent.

The other thing I can’t stress enough. MARK EACH DRIVE as soon as you remove it from the array. All the information to use the array is on the drives, but if you screw up the disk order, no promises this will work, in fact it’s a good bet it will not.

I hope this helps someone else who is in the middle of a panic. A failed server is never fun, but this turned out to be a lot less pain than I initially feared.


HP Abandons Windows Home Server

Well, we seem to have had a bunch of HP related posts lately. This one is pure bad news, however. HP has decided to stop supporting Windows Home server. As reported on WeGotServed.com, HP has stopped selling or developing any servers for the WHS market, effective immediately. HP, of course, claims this has nothing whatsoever to do with the announcement from Microsoft that they were abandoning Drive Extender in the next version of Windows Home Server, code-named Vail. Yup, sure. I believe that.

So where does this leave my little MicroServer? I’m not really sure. But since HP hasn’t announced anything about Windows Storage Server 2008 R2 Essentials, or Windows Small Business Server 2011 Essentials (aka, Aurora), I’m hopeful that they will continue to support those of us who think that small, inexpensive, well-designed, and well-built servers have a place in the SMB market.


HP ProLiant ML350 G5 Server– RIP

Well, it’s been an interesting time with this ML350. It has done yeoman duty as my primary Hyper-V server for 3 1/2 years now. We’ve had good experiences, and bad experiences. Especially during the Power Supply mess three years ago, but it’s also been prone to misbehaving in any sort of power event, even though it’s been sitting behind a pretty decent UPS. And it eats SAS drives – I’ve had 4 or 5 of them fail. Now in fairness to everyone, this machine was completely maxed out. It had 16 GB of very expensive and very power hungry FBDIMMs, which produced a lot of heat. Eight 2.5”, 15,000 RPM drives didn’t help, but to make life more fun, I added 4 additional SAS drives off an Adaptec controller for boot and miscellaneous storage. So the inside of this server ran quite warm, pretty much 24/7.

And yesterday, as I’m sitting working at my desk, I heard it power down. It took a while to sort out things, but I finally deduced that it was reporting 2 failed CPUs. Now I seriously doubt that both of them spontaneously failed at the same moment, so I’m much more inclined to suspect something on the motherboard failed. In any case, we’re dead. And unfortunately, all my contacts at HP Canada have moved on to other worlds and places, so there’s not a whole lot I can do with this now very heavy doorstop. But it’s been a valuable and appreciated resource while it lasted. I hate to lose it, and it will make life here “more interesting” as I juggle environments and machines.


New HP in the House

A new HP Proliant MicroServer just arrived in the office. And it is a sweet little gem. Small, square, and light in weight, this little server packs a decent punch. And is completely quiet. Mine came with 2 GB of RAM, and 2x 1TB hard disks, but it can hold 8 GB of RAM (2 slots only), and 4 internal 3.5” SATA hard disks. Plus an eSATA slot and 6 USB2 slots, so we’re not likely to run out of hard disk space very quickly.

The first thing I did was slot in a couple more 1TB hard disks I had available, bringing the raw storage up to 4 TB. The MicroServer only understands RAID 0 and RAID 1, so that’s going to mean only 2TB of useable space after I configure this for RAID 1. Still, that should be just fine for our needs as a Windows Storage Server 2008 R2 Essentials server. We’ll use it primarily as a Windows Storage Server 2008 R2 Essentials fully domain integrated client backup solution, since that’s our primary requirement here. But we’ll also take advantage of this server to provide a single place to hold our Audible and Kindle books, and as our TiVo Desktop Plus server, holding TV shows we’ve recorded but run out of space for on our two TiVos.


Windows Storage Server 2008 R2 Essentials Announced

Those folks at Microsoft who bring us Windows Small Business Server and Windows Home Server have a new product coming out soon – Windows Storage Server 2008 R2 Essentials. This is based on the same code as Windows Small Business Server (SBS) 2011 Essentials, but focused on providing client backup and network storage for existing business networks. See Sean Daniel’s blog post for pictures and details.

Windows Storage Server 2008 R2 Essentials can be joined to a regular Active Directory domain, and can integrate users from that domain. This makes it a perfect companion to an SBS network to handle all your client backup needs. Windows Storage Server 2008 R2 Essentials is limited to 25 users and 25 clients, but you can have multiple Windows Storage Server 2008 R2 Essentials devices joined to the domain, so that limitation isn’t a big issue.

Windows Storage Server 2008 R2 Essentials will also include the Remote Web Access portal that Windows SBS 2011 Essentials has, if you need that ability, but if you’re using it as part of an SBS network, you’ve already got that covered.

I’ve been testing a very early version of the product, and I’m really impressed. This is definitely going to be a winner in the SBS space to solve the client backup concerns our customers have.

Windows Storage Server 2008 R2 Essentials will be, at least initially, only available as an OEM integrated product. But as part of an HP MicroServer, for example, this looks like a real winner.


MVP Award Again

I just received my notice that I’ve been awarded MVP status for the 11th straight year, this year as a Windows PowerShell MVP again. And while I’ve seen a lot of changes in the MVP program over that time, not all of them ones that I like or approve of, I continue to value the award for the company it puts me in—that of people I respect who truly care about the community we all are part of, and who give of their time and expertise to help that community prosper and grow. I believe in that, and my fellow MVPs believe in that, so it’s a proud and good family to be part of.

Charlie Russel

Windows Storage Server 2008 R2 Releases

According to the Windows Storage Server blog, Windows Storage Server (WSS) 2008 R2 has released. This now includes three SKUs – Workgroup, Standard and Enterprise. At the lower end, the Workgroup product is limited to 25 users, and won’t do clustering. But does do iSCSI support, and would be ideal in a small Hyper-V environment. We’re also hearing reports of new “cluster in a box” implementations that leverage the new high availability bits built in to WSS 2008 R2.

I’m hoping to get my hands on a review unit to test, and if I do, we’ll have a full report on both the hardware and the new software. Overall, I’m pretty excited.