How to: Automatically log your PowerShell session every time

How to: Automatically log your PowerShell session every time

Preface

At SharePoint Saturday New Hampshire I sat in a packed room and listened as Todd Klindt showed everyone how to install SharePoint 2013 without screwing it up (too badly). The big take away for me was this command that I had not heard about before called start-transcript. The power of start-transcript is that it is able to write everything that you do in a PowerShell session to a log file that you can review later. Todd demo’ed how he throws this every time he opens PowerShell and has found it to be invaluable.

The main reason that I had not heard of start-transcipt before is that I live in PowerShell ISE and rarely (if ever) go into plain ol’ PowerShell, and sadly start-transcript is not supported in PowerShell ISE. DAMN YOU POWERSHELL GODS FOR TEASING ME SO!!!!

The Use Case

The problem that this solves in my view is:

  1. I spend a ton of time tweaking away at some code on a SharePoint server, get it right and then inadvertently close the PowerShell window. It’s just GONE.
  2. Opening and closing PowerShell windows and trying to remember what I manually typed 2 hours ago to fix a problem that got reintroduced after redeploying code.
  3. Needing a way to review who made changes to the serverenvironment and see what they actually did.

The more I thought about it the more the more I liked the ability to log everything that is done in PowerShell on a server, but the issue that I had was that it was something that the person opening PowerShell had to remember to do every time they opened a window.

I started thinking about using PowerShell profiles to implement this for every user. In my experience I have seen profiles used infrequently, but in a couple of the scenarios they have been deployed via AD Group Policy. However if you are working in an environment that you don’t have access to create GPOs or you are working in a development environment and developing GPOs just isn’t your thing what do you do?

The Problem

The task at hand was two-fold:

  1. Auto deploy a PowerShell Profile for SharePoint Admins that would be lightweight, contain the start-transcript function to start automatically, assist in auditing, and be Server Administrator deployable
  2. Figure out if start-transcript like functionality was available for the native PowerShell ISE

The Solution

The solution that I came up with was to leverage the All Users Startup option in Windows to launch a script that would check to see if the folder that holds the PowerShell profile scripts exists. If it exists, the script terminates and all is well. This happens on every interactive login, but takes only a second. If the folder does not exist, the will kick off a creation of the scripts based upon a preset profile definition that includes the targeting & naming of the logs, starting the transcript, and loading the SharePoint module. The profile definition can be completely customized making this a viable approach for admins of other technologies, not just SharePoint.

For PowerShell this is great because it works out perfectly as built. PowerShell ISE on the other hand is still a thorn in our sides. The Scripting Guys, aka Ed Wilson and Craig Liebendorfer, wrote a terrific function that allows you to log the output pane in PowerShell ISE v1 & 2. Sadly this is not working in PowerShell v3 since there is no output pane. Leveraging that we can get part of the functionality in ISE that we get in the command-line version.

Behind the code

The solution that I came up with is in the form of a single PowerShell script that builds the following:

  • 2 folders (at the Root of C:)
    • c:PowerShellLogs will house all of the transcripts
    • c:PowerShellScripts will be the home for the scripts used to build the profiles and will be the default starting location when PowerShell opens. This way you can put all of the scripts you want to call in one place for all users and they can launch them easily.
  • check-profiles.lnk (in the All Users Start Menu Startup folder)
    • This shortcut points to a batch file in the C:PowerShellScripts folder called check-profiles.bat
  • check-profiles.bat (in c:PowerShellScripts)
    • This batch file launches the check-profiles.ps1
  • check-profiles.ps1 (in c:PowerShellScripts)
    • This PowerShell script checks to see if the user has a WindowsPowerShell folder in their My Documents folder. If it finds the folder, the script terminates. If it doesn’t find the folder it launches the create-profiles.ps1 script
  • create-profiles.ps1 (in c:PowerShellScripts)
    • This PowerShell Script creates the profiles for both PowerShell & PowerShell ISE.

Here is what I put in the PowerShell profile:

  • Set the location for PowerShell to start in to C:PowerShellScripts
  • Display a message about needing to Run as Administrator to effect changes
  • Set the path for logging the session to C:PowerShellLogs
  • Set the log name using the user context and date time stamp
  • Start the transcript
  • Display a message about waiting for the SharePoint snap-ins to load
  • Load the SharePoint snap-ins
  • Display a message that loading the SharePoint snap-in is complete and lets you know who you are running PowerShell as

Here is what I put in the PowerShell ISE profile:

  • Set the location for PowerShell to start in to C:PowerShellScripts
  • Display a message about needing to Run as Administrator to effect changes
  • Set the path for logging the session to C:PowerShellLogs
  • Load a function to set the log name using the user context and date time stamp
  • Load the function for Output-ISETranscript (the Scripting Guys code)
  • Display a message about waiting for the SharePoint snap-ins to load
  • Load the SharePoint snap-ins
  • Display a message that loading the SharePoint snap-in is complete and lets you know who you are running PowerShell as

Conclusion

While its may not be the perfect solution for PowerShell ISE that I was looking for when I set out, at the end of the day with this code I now have the ability to automatically log everything done in command line PowerShell.

Thanks to Todd Klindt, Evan Riser, Mark Rackley, and Dan Holme for talking through these use cases, reviewing some of the code, and taking differing view points on this to validate that it is a reasonable approach or not. I love being a part of a community where bouncing ideas and solutions off of peers is so easy and open.

You can find the code here:

powershell Jason’s code on GitHub

Hopefully this code will be useful to you in your day to day world.

Comments are closed.