Browsed by
Tag: Troubleshooting

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 notepad

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

When in doubt, check ALL the permissions…

When in doubt, check ALL the permissions…

Having just completed my last speaking engagement of 2012 it was time to get back into the swing of things and start playing with troubleshooting a bit. 

The dilemma

In a continuing effort to evolve my PowerShell build script for SharePoint I spent a few hours with my team playing with different settings.  One of my team members was driving to get better hands on experience with using PowerShell to configure SharePoint.

We started with the very standard PSConfig script that I have used hundreds of times in the past:
(I left out the variables to save some space)

1

The following error popped its ugly head up in PowerShell’s angriest color when attempting to run this initial farm configuration:

New-SPConfigurationDatabase : Requested registry access is not allowed.

The troubleshooting

Check permissions

Hackles went up immediately when the error was read out loud.  Prior to running the script we had just walked through several Security Best Practice checks, following Microsoft’s guidance in TechNet, partly to see if anything had changed recently (it hadn’t) and partly as a good refresher:

Account permissions and security settings (SharePoint Server 2010)

Plan administrative tasks in a least-privilege environment (SharePoint Foundation 2010)

Plan for administrative and service accounts (SharePoint Foundation 2010)

We went back and doubled checked all of our settings and found that things were configured as prescribed.  The SharePoint install account had local administrator permissions on the SharePoint server and SecurityAdmin and DBCreator rights on the SQL server.

Examine the logs

We visited our Server Event Log and 14 Hive Logs folder but found no evidence that anything was in error.  In fact, no logs entries were created at all…

Check the firewall rules

We validated that for this configuration, in a sandbox without external connections to the world, that the Windows Firewalls were turned off.

Check the connection between servers

Using the trusty Data Sources (ODBC) validation method we were able to make connection from the SharePoint server to the SQL server, and browse the available databases.

Get thyself to Google!

Completely perplexed at this point by an error that doesn’t make any sense due to the fact that the SharePoint install account was a local admin we went to our good friend Google and found, well to be honest a bunch of crap that didn’t help us in any way.  Lots of stuff for people who have lost access to Central Admin due to GPO changes, or had a driver go corrupt, or are trying to write to the registry using C# in ASP.net, & even a forum about people having problem registering their car in Nebraska.

Review of Local Security Policies

One last ditch effort to check the local security policy to see if a new GPO pushed down changes to turned out fruitless, however one of the AD admins mentioned they had seen an issue similar to this once before they changed the User Account Control Settings (UAC). 

The Root Cause

Not even thinking about it my response to the UAC question was “There is no need to do that, you just right-click and launch as Administrator or use my PowerShell script to run as a different user

Upon examination of my team member’s screen it was revealed that: 2

PowerShell ISE have in fact been opened without being run as Administrator.  A costly lesson from a time perspective, but a good learning experience for a newbie at PowerShell for SharePoint.

The most troubling of all however was upon reexamination of the PowerShell error message we needed to only go 2 lines above the big red error message that we were troubleshooting on, to the plain black texted TRUE error: (highlighted here in yellow)

3

Unassuming and unnoticed as we troubleshot the obvious error, the line was thrown by the PSConfig.exe and not a bad PowerShell parameter which explains why PowerShell did not recognize it as an error.

The moral of the story…

Even after following every documented Best Practice out there, we still were able to find a way to cause an error.  While the UI was bad for the error that would have been useful to us, it was at least thrown in our faces.

The easy answer is to always make sure that you open PowerShell or PowerShell ISE as Administrator.  My personal preference is always going to be login in to servers using a non-SharePoint privileged account and then elevate permissions to run in the context of a SharePoint Farm admin or service account as demonstrated in my previous post which sets the run as Administrator for you.

Be sure when you are ready to do any SharePoint Admin work that you see the “Administrator:” in front of your PowerShell ISE path, like this:

4

At the end of a fun troubleshooting session we walked away with a new notch in our troubleshooter tool belt, a fun article to write, and team member who will never forget to fire the RunAs flag ever again.