The SQL Workbench

(Steve's Site)

The SQL Workbench - (Steve's Site)

PowerShell Profile for SQL Server DBAs

OK so you have PowerShell installed, but when you start it up it drops you some where in C:\Windows\System32\WindowsPowerShell or somewhere similar.  When you change directories your prompt keeps changing.  You don’t have easy access to the tools you want to use.  To add insult to injury you don’t have access to those really neat SQL Server powershell cmdlets everyone is using.  (Note: the SQL Server snapins as a whole are great)  So what is the easiest way to solve this issue is to create a profile.  What does this mean, basically its a script that runs when you start up PowerShell that sets up your PowerShell environment.  For an review of what profile script is please check here and or here.  I’m going to give you some suggestions and show you what I have in my profile script as well as walk you through setting it up.

First off were to stick it, there are a few choices, my favorite is in a file simply called profile.ps1 in the %UserProfile%\My Documents\WindowsPowerShell\ directory.   This way it applies to only the current user but it will affect all PowerShell shells created.  If you put the same script in a file named Microsoft.PowerShell_profile.ps1 it would affect only the Microsoft PowerShell Shell and nothing else.  There are locations so the profile script will affect all of the users on the system but I shy away from that (%windir%\system32\WindowsPowerShell\v1.0\ aka $PWD).  Once again the name of the file will affect which shell it affects.
Quick Overview

  1. Profile.ps1 affects all shells
  2. Microsoft.PowerShell_profile.ps1 affects only the Microsoft PowerShell Shell
  3. The user profile directory will affect only that particular user
  4. The PowerShell directory will affect all users.

Second, what do you want it to do?  I have a few things I like my profile script to do:

  1. Set up my prompt, this is the number one thing for me.  I do not like the standard prompt.
  2. Set up easy to use functions so I can call standard executables easily passing parameters to them in a no fuss manner.
  3. Set up easy to remember and type variables I need.  (File locations,directories, or anything else I need)
  4. Set up easy to remember and type psdrive locations.  (I know 2 and 3 are very similar)
  5. Load up any PowerShell Plugins and Providers I use on a regular basis.
  6. Load any functions I use, either directly or through loading a secondary script.

Third, you have to enables scripts…this could be a touch subject from a security stand point.  I probably break all the rules an enable all scripts to run on my machine. (To learn more please look at:

get-help about_signing

) Basically you need to allow you machine to run scripts, for this example I’m going to set my execution policy to “Unrestricted”.  This obviously is not the most secure setting for Powershell.  Please take the time to look into this setting before you change it.

Set-ExecutionPolicy -ExecutionPolicy Unrestricted

Fourth and finally put your script where you want it to go, and open a Powershell session. That is it. Here is my basic script:
Section 1:

#--------------------------------------------------------------------
#			VARIABLES
#--------------------------------------------------------------------
$sqlIO="C:\Program Files\SQLIO\sqlio.exe";
$textpad = 'C:\Program Files\TextPad 5\TextPad.exe';
$_SQLProj = 'C:\Documents and Settings\sfibich\My Documents\SQL Server Management Studio\projects';
$_WPS = $home+'\My Documents\WindowsPowerShell';

OK in this section I’m just setting a bunch of variables that I use often. I have both paths to executable and folder paths. I could make the folder paths in psdrives with New-PSDrive but for some reason I find it more useful as variables.

Example:

set-location $_WPS;

Section 2:

#--------------------------------------------------------------------
#			FUNCTIONS{}
#--------------------------------------------------------------------
function textpad ([string]$fileName) {&$textpad $fileName};
function sqlIO ([string]$parms){&$sqlIO $parms};
function get-cmdlet () {
	get-command -type cmdlet |
	sort -property psSnapin,name |
	format-table -property psSnapin,name
};

Functions, mainly I use them to wrap executable that I may want to pass a parameter to when I start it up. The one I use the most is textpad. I got SQLIO working but it was tricky to get everything passed to it correctly, I’m sure I could come up with some a little more elegant in the future but for now that’s what I use(I hate to admit it but I normally use good old CMD when using SQLIO). The get-cmdlet just list commands with which snapin in came from. This can be helpful if I’m looking to install something on a new machine and I can’t remember where the command came from.

Section 3:

#--------------------------------------------------------------------
#			FILES
#--------------------------------------------------------------------
#$fileContents = [string]::join([environment]::newline, (get-content -path $_WPS\function_ScriptName.ps1))
#invoke-expression $fileContents

Nothing to see here, move along. This is where I would put other scripts that I want to incorporate into my PowerShell profile. I can’t remember where I picked up the script to bring other scripts in but its nice. Currently I don’t have any other script functions I want to inline into this script but I keep it as a place holder.

Section 4:

#--------------------------------------------------------------------
#			PROMPT
#--------------------------------------------------------------------
function prompt {"[$env:computerName]>";
$host.UI.RawUI.WindowTitle = $(get-location)
};

If there is a reason to have a custom profile this is it, or at least for me. I can’t stand the prompt ever changing as I move through different directory structures. This nice prompt is short a sweet. It gives you the name of the computer, in case you are on in a VM and don’t know. It also puts the current drive location up in the window title of the powershell window you have open. That is the nicest part. I found this $host.UI.RawUI.WindowTitle piece years ago on someone else’s blog, and I wish I could remember who so I could give them credit but we all stand on the shoulders of giants.
Section 5:

#--------------------------------------------------------------------
#			LOADING SNAPINS AND PROVIDERS
#--------------------------------------------------------------------
 
#------------------------
#	SQL
#------------------------
$ErrorActionPreference = "Stop"
$sqlpsreg="HKLM:\SOFTWARE\Microsoft\PowerShell\1\ShellIds\Microsoft.SqlServer.Management.PowerShell.sqlps"
if (Get-ChildItem $sqlpsreg -ErrorAction "SilentlyContinue")
{
    throw "SQL Server Provider for Windows PowerShell is not installed."
}
else
{
    $item = Get-ItemProperty $sqlpsreg
    $sqlpsPath = [System.IO.Path]::GetDirectoryName($item.Path)
}
 
# Set mandatory variables for the SQL Server provider
Set-Variable -scope Global -name SqlServerMaximumChildItems -Value 0
Set-Variable -scope Global -name SqlServerConnectionTimeout -Value 30
Set-Variable -scope Global -name SqlServerIncludeSystemObjects -Value $false
Set-Variable -scope Global -name SqlServerMaximumTabCompletion -Value 1000
 
# Load the snapins, type data, format data
Push-Location
cd $sqlpsPath
Add-PSSnapin SqlServerCmdletSnapin100
Add-PSSnapin SqlServerProviderSnapin100
Update-TypeData -PrependPath SQLProvider.Types.ps1xml
update-FormatData -prependpath SQLProvider.Format.ps1xml
Pop-Location
 
#------------------------
#	TFS
#------------------------
#Add-PSSnapin Microsoft.TeamFoundation.PowerShell

Can you say Snapins…this is where I load them. Most of the time I do SQL development so SQL Server Snapins and TFS Snapins are all I need. If I have something else I would load it in this section. The TFS snapin is pretty straight forward. The SQL snapins load steps are extensive and can be found here.
Section 6:

#--------------------------------------------------------------------
#			FINAL
#--------------------------------------------------------------------
sl $_WPS

The end all I’m doing is setting my locations to a variable I set earlier which is inside of my local documents PowerShell folder.

Well I hope that tour through my profile.ps1 has given you some ideas. Its pretty simple to set up and once you have something that can make PowerShell your own it will inspire you to do more.

Two quick related links:
PowerShell Scripting Games for 2012 are up and running.
and
SQL 2012 PowerShell extensions are out! (Disclaimer I have not had any time to play with them but they sound pretty neat!)