Posts Tagged ‘PowerShell’

What’s that IIS Process ID again?

Sunday, August 18th, 2013

First off, I’ll admit that it has been some time since my last post. I’ve moved into a new role at work that has much less emphasis on day-to-day development. However, I’ll still plan on posting interesting tidbits from time to time as I encounter them – just as I always have!

This one came up during a recent sprint of coding in which I was debugging a SharePoint 2013 farm solution (I know – apps are the way to go now!) with Visual Studio 2012. Let me say, since first starting development in MOSS 2007, this is a totally different and much smoother experience. I switched back-and-forth between using Visual Studio’s “Play” button – also known as “Start Debugging” – and a more traditional Build, Deploy, Attach to Process method.

When looking to attach to IIS, it’s always a gamble as to which w3wp.exe process to attach. However, this can be avoid by using the appcmd.exe utility. There is a nifty set of parameters that will allow you to view the currently running w3wp processes, their process IDs, and the names of the associated application pools. It’s just the right amount of information.

Enjoy and happy debugging!

VirtualBox and Multiple Monitors

Thursday, July 26th, 2012

As a SharePoint consultant, I really enjoy having a local copy of a full SharePoint server on my laptop. As I am patiently waiting for Windows 8 to release with Client Hyper-V, I’m continuing to use Oracle’s VirtualBox software to host my SharePoint development environments.

With my current engagement, I find myself in my client’s offices Monday through Thursday and at my office on Friday. At my office, I have an external monitor that I use in addition to my laptop’s screen. At my client’s offices, I just have my laptop’s screen to use. Whenever I’m able to have a secondary monitor connected, I like to use VirtualBox’s multiple monitor support to show my VM on both of my screens. VirtualBox achieves this look by opening two windows – each window meant to be maximized on one of the two monitors.

On Fridays I get to use two monitors with two VirtualBox windows. However, come Monday, I typically forget to reset the virtual machine back to one monitor. Even though I’m only using one monitor, VirtualBox still opens two windows for me! With only one monitor, this makes the VM very tough to use. The only remedy is to shut down the VM, reconfigure the setting, and restart the machine; a process that can be quite lengthy on a server with SharePoint 2010 and SQL installed!

I turned to PowerShell to help ease my Monday morning woes. I developed the script below and put a link in my Startup folder so that, each morning when I boot my laptop, all of my VirtualBox VMs will be automatically configured to use the number of monitors that I currently have connected to my laptop.

Fair warning – this was a quick script just for my personal use. While it should work for you, it does not have any error handling to report if things go awry. See the comments in the script for details.

Extracting Zip Files using PowerShell

Tuesday, July 17th, 2012

To help troubleshoot some SharePoint issues, I had a need to analyze some log files that were contained in multiple zip files; one log file per zip file. Since there were several hundred zip files to extract, I figured PowerShell could help! There are several posts I found with example scripts for how to perform this operation. I took pieces from many posts, added some COM object clean-up code, and wrapped this in a function. I hope it helps you in your scripting activities!

The code below is the function I’m using to extract a single zip file. It leverages the Windows Shell COM object (i.e. Windows Explorer) to extract the files by exploiting the fact that Windows Explorer treats zip files as folders. Therefore, the operation can leverage existing file copy methods between two folders.

Latest Code Not Working Quite Right?

Tuesday, July 3rd, 2012

I’m going to start this post with an example. See if you have ever found yourself in this situation when working on developing updates for previously deployed code; most often in a test and/or development environment:

1. I start out with an existing feature receiver that uses a web-scoped feature. The feature is already deployed to my development environment. To make this example very simple to illustrate the issue – this feature receiver will set the web’s title to an arbitrary value. The title will be reset back to its original state when the feature is deactivated.

2. Activating the feature on my test site reveals the following site title change.

3. Now I’m going to illustrate a change to my previously deployed code. Let’s say for example that I wanted the title to be changed to “*** NEW WEB TITLE ***” instead of “EXISTING WEB TITLE”. I’ll make the change on Line 16 of the code above and create a new WSP for deployment.

4. I then open a new PowerShell window and execute the following six PowerShell commands using the same window. These commands will deploy the latest code and reactivate the feature on my test site so I can see the latest change.

5. I will then visit the site to see the change…

What happened? The title didn’t change?! What is wrong?

The problem occurred during Step 4. When the first command deactivated the feature, that cmdlet called the SharePoint DLLs which in turn called the SMayes.SharePoint assembly. This loaded the assembly in the PowerShell.exe process. Once the assembly is loaded, it will not be unloaded.

That’s the issue here: Once a DLL is loaded in a .NET process, it will not and cannot be unloaded!

So what? This means that when I executed the Enable-SPFeature cmdlet, PowerShell was still referring to my old code that was loaded earlier and therefore was not using my updated code! Opening a new PowerShell instance and executing the activation in that instance will cause the latest code to be used since the new process will be getting the updated DLL from the GAC.

In summary: Whenever you are deploying code updates, the proper way to execute the redeployment would include closing the current PowerShell process and opening a new PowerShell process as soon as new assemblies are deployed. This will ensure that further commands, such as feature activations, will not use outdated code.

Note that while the issue I described above pertains specifically to a feature receiver, it would also equally pertain to an event receiver, timer job, or other piece of code within a deployed assembly called by the SharePoint API. This issue is also a general issue across the board whenever a process (PowerShell, W3WP, OWSTimer, etc.) is using a custom-built assembly. This is why, when deploying new assemblies, W3WP is typically recycled. Also ensure that OWSTimer is recycled if there are any timer jobs being deployed.

Happy coding!

Adding a PowerShell Snap-in

Tuesday, May 29th, 2012

A typical scenario when developing PowerShell scripts for SharePoint is to need the use of the SharePoint PowerShell snap-in. This snap-in provides all of the great SharePoint cmdlets that have quickly become critical to any SharePoint developer or administrator’s toolkit.

Some scripts may assume that the script will be executed within the SharePoint 2010 Management Shell – which is simply a standard PowerShell window with some extras: including the SharePoint PowerShell snap-in. However, what if an unsuspecting or unexperienced administrator executes the SharePoint script in a standard PowerShell instance?

To cover this circumstance, most script developers will choose to add the snap-in at the beginning of the script using the following code.

While this seems sufficient, there is an issue if the snap-in has already been added. This would easily occur if the script was run within the SharePoint 2010 Management Shell. PowerShell reports the following error pertaining to the fact that the snap-in has already been added:

Add-PSSnapin : Cannot add Windows PowerShell snap-in Microsoft.SharePoint.PowerShell because it is already added. Verify the name of the snap-in and try again.
At line:1 char:13
+ Add-PSSnapin < <<< Microsoft.SharePoint.PowerShell -PassThru + CategoryInfo : InvalidArgument: (Microsoft.SharePoint.PowerShell:String) [Add-PSSnapin], PSArgumentException + FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand

A typical solution to this issue I’ve seen is to instruct PowerShell to ignore the error using the following code.

That bothers me. I should be looking to suppress only the error where the snap-in is already added. What if I get another unrelated error? Therefore, instead of instructing PowerShell to silently continue, I would prefer the following code below. This code first checks for the snap-in before adding it and also allows for unrelated errors to still be reported.

It should be noted that this code could be used with any snap-in; not just SharePoint’s PowerShell snap-in. Here is a function one could use for any snap-in.

Finding Files Linked To A Specific File (Publishing Pages Linked to a Specific Page Layout)

Monday, March 19th, 2012

Ever had a need to find all of the files in a site collection that link to a specific file? A colleague of mine made an excellent find a few weeks ago and taught me this gem from the SharePoint object model. He had a need to find all publishing page layouts on a site and catalog which were being used and which weren’t. Check out his post here: SharePoint Fix: Powershell script to get SharePoint Page Layouts inventory and its usage across site collection

SharePoint Diagnostic Studio Logon Failure

Monday, February 6th, 2012

I was introduced to the SharePoint Diagnostic Studio 2010 at the Microsoft SharePoint Conference 2011 in Anaheim, CA. I was very excited about its capabilities and have just gotten around to testing it in the last couple of days.

After configuring PowerShell remoting between my laptop and my development server, I set out to create a new project in the SharePoint Diagnostic Studio and see what it could do. Upon creating a new project, I entered my credentials. After a few moments, I received the following message.

It appears the new project installation was not successful. Click OK to see the error message

After clicking OK, the error log is opened. If it does not open for you, my log was at %HOMEPATH%\Documents\SharePoint Diagnostic Studio\Server Extensions\Error.log In the error log, I saw the following message.

Logon failure: unknown user name or bad password.

After getting quite paranoid about being up early in the morning with my two-month old and perhaps not remembering any of my passwords, I started to investigate things on the server to see if I could figure out what was going on. What I found has to do with my configuration of CredSSP authentication.

With CredSSP authentication, there are two preferred/secure ways of submitting credentials: Kerberos authentication and Certificates. These required extra configuration of PowerShell remoting that I haven’t quite gotten to just yet. Therefore, my remoting capability was relying on the third and less secure way of submitting credentials: NTLM.

It turns out, after investigating my server’s security log, the SharePoint Diagnostic Studio (or perhaps the underlying PowerShell commands) are attempting to first authenticate using Kerberos. That fails and I would expect that since I didn’t do all of the necessary configuration for Kerberos to work. However, it then falls back to NTLM. To my surprise it does not use the credentials I had specified. Rather, it was using my local laptop credentials!

To trick any application in to sending other credentials when it wants to send the credentials of the currently logged in user, you can use the Runas command which allows one to execute any program under another user. For this instance, SharePoint Diagnostic Studio shouldn’t run under the remote account. It should run under the local account, but use the remote account for any remote access. Thankfully, Runas has just such a provision – its /netonly switch! The following command will open SharePoint Diagnostic Studio under the local account while using the remote account to access the remote server.

runas /netonly /user:DOMAIN\USERNAME "C:\Program Files\Microsoft\SharePoint 2010 Administration Toolkit\SPDIAG.EXE"
(The Runas command will ask for a password before launching SharePoint Diagnostic Studio.)

Have fun!

Access Denied when Enabling PowerShell Remoting

Thursday, February 2nd, 2012

Quick tip: Are you receiving Access Denied messages when you are attempting to run the Enable-PSRemoting cmdlet? I’ve received them on machines connected to a domain, even when I’m running in an elevated PowerShell window. An easy trick is to open a PowerShell window as the built-in administration account on the machine. Not sure why, but for whatever reason, it seems to work!

Finding Sites with a Particular Feature Activated

Saturday, February 12th, 2011

I continually have a question arise that seems easy to answer, yet from what I can tell, is not yet available with SharePoint out-of-the-box in its user interfaces. That question is:

What are all of the sites with feature xyz enabled?

A few years ago with a MOSS 2007 client environment where I had to answer this question, I was left with writing a quick C# console application that would crawl a web application for me and discover all of the site collections with a particular feature enabled. Not quite the best way of doing things, but it’s what was the best at the time.

Fast forward to SharePoint 2010. Now, PowerShell is in the mix and required for all SharePoint installations. Thanks Microsoft! So now, I have the vast capabilities of PowerShell available on any SharePoint farm I may encounter on any client environment with which I may be working. Plus, there’s an added bonus that, for some reason, the word “script” seems to scare clients and IT departments less than “console applications”. Even though PowerShell scripting can often wield the same powers as a C# console application, it seems to be accepted with more ease which makes my life easier.

Now that PowerShell is widely available, I rewrote that “quick C# console application” I referenced above in PowerShell for use recently on a SharePoint 2010 environment. The script below has a slightly more specific task than solving the question I posed above:

Output all of the site collection URLs within a particular web application that have a particular site-scoped feature enabled.

Here’s my script to do just such a task. The code below is meant for a single ps1 file.

Please note that it should work with both the 2007 & 2010 SharePoint product lines: SharePoint 2010 (Foundation & Server), WSS 3.0, and MOSS 2007. I have only tested this code on a SharePoint Server 2010 environment, but have no reason to believe it wouldn’t work in the other environments.

Feel free to use this script or modify it to fit your needs. There are several extra features that could be added to this script to make it even more versatile:

  • Reporting on the status of multiple features, not just a single feature
  • Reporting based on feature name versus feature GUID
  • Reporting on features scoped at different levels besides Site
    • Farm
    • Web Application
    • Web
  • Crawling other scopes besides a single web application
    • The entire farm,
    • Multiple web applications,
    • A subset of site collections,
    • A subset of sites,
    • Based on another block of script and/or function call to determine if a site should be scanned by the script,
    • etc.

I think the above script is a great starting point. Hopefully either myself or someone will get around to adding the above suggestions. Please share in the comments if you do end up extending this script!