Friday, November 12, 2010

Setting default environment variables for PowerShell

I'm frustrated right now.  You probably understand.  I've been a command-line junkie since the early days of DOS and I always prefer the bash shell when working with Linux.  PowerShell has been around for several years now, but I've never felt the need to embrace it, which is probably foolish and short-sighted of me, but that's just how I've felt.  I'm working on my new BIND DNS book (shameless book plug:  check out my Amazon author's page and buy lots of my books), which will, of course, include utilities such as whois, host, dig, and other tools that are traditionally the domain of Linux and Unix users.  The reality of the world today is that lots more people use the Windows operating system than Linux or Unix, so there are ports of those tools for Windows users and I need to include them in my book.  I decided, if I was going to include Windows command-line stuff, to go with PowerShell.  It is, after all, supposed to be the latest and the greatest.

I wanted to be able to unzip files at a command-prompt and use utilities like wget, dig, whois, etc.  Of course, if you're working in a command-line environment, you need a zip/unzip utility, so I chose 7-Zip.  I downloaded all of the various tools to a directory (oops, I mean folder) and proceeded to set environment variables so I could use them from any directory (oops, I mean folder) on the computer.  I did the usual stuff which you're probably familiar with:  I went to the System Properties>>Advanced System Settings and clicked the button for Environment Variables.  Then I went to the System variables section and modified the path to include the location of the various utilities, especially 7-Zip.  I rebooted my system and all of the new paths worked in PowerShell except 7-Zip.  I couldn't execute "7z e", for example, to extract the contents of a zipped file.  I rechecked everything to make sure I hadn't fat-fingered anything, and everything was fine.  Still, I kept getting the error "Bad numeric constant: 7".  Huh?  I Googled and discovered that Windows PowerShell doesn't like executables that start with a numeric character!  Huh!  What kind of BS is this???  Oh well, it is what it is and I can't change that, so I decided to create an alias so I could start "7z" with "sz" instead.  Makes sense, right?  I entered the following command in PowerShell:  set-alias sz "c:\program files\7-Zip\7z.exe" and, voila, the alias worked great.  Except for one thing; when I shutdown and restarted PowerShell, the alias went away.  Grrrrr.  Well, I'm new to PowerShell, but there had to be a way to create persistent aliases, right?  Well, yes, but it ain't very easy, thanks to Windows security settings.  You have to add the alias to your profile.  Here's how I got it to work.  First of all, I created the profile.  Here are the steps:
  1. Find out where PowerShell thinks your profile is located with the $profile command.  Mine was located at C:\Users\don\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1.  The WindowsPowerShell directory did not exist, nor did the file Microsoft.PowerShell_profile.ps1, so I had to create both of them.
  2. Use the command "notepad $profile" to open your profile for editing and enter the alias in the file:  set-alias sz "c:\program files\7-Zip\7z.exe"
  3. Save the file.
  4. You would think that would do it, but if you exit and restart PowerShell, you'll get a big fat permissions error saying bad things about scripts and configuration files (\Microsoft.PowerShell_profile.ps1 cannot be loaded because the execution of scripts is disabled on this system.).  Turns out you have to set signing permissions for the configuration file in order to make this work.
  5. Close PowerShell and re-open it as Administrator.
  6. Use the command Get-ExecutionPolicy to see the current execution policy setting.  Mine was set to restricted, which is one of the four values available:  Restricted, AllSigned, RemoteSigned, or Unrestricted
  7. I'm not going to go into the security implications of each of the settings, but you really should  read up on Set-ExecutionPolicy before messing with these settings.  You've been warned.  I then used "Set-ExecutionPolicy RemoteSigned" to modify the script/configuration security settings to allow PowerShell to read the new profile.
  8. I restarted PowerShell and now my alias worked fine.
  9. What a pain-in-the-neck.  I hope this helped you!  Let me know if I overlooked anything.
Oh, in addition to my BIND DNS book on Amazon, check out my BIND DNS workshop at

No comments: