Just Add Code

Archive for the 'PowerShell' Category

DevConnections 2008: Automating Common Tasks with PowerShell

One session down, two to go! There was a good turnout at today’s session, about half the people had worked with SharePoint, and the other half were new. The audience members had some great questions about using PowerShell and SharePoint.

Below I have a text file with all the commands I entered during the session (thanks ‘get-history’), the script library file that I used for the demo and the slide deck. If you are looking for the IDisposable or the PowerShell web part stuff its not in either of those. I’ll be putting those up in separate posts, the web part because I want to clean i up and IDiposable because I want a little more testing before I unleash it on the world.

I’m also interested in feedback with the SharePointCmds.ps1 file in terms of what is useful and what commands are missing. If people find value in it I’ll maintaining it, extend it and generally make it more useful. Feel free to drop me any comments.

Automating Common Sharepoint Tasks with PowerShell

SharePointCmds.ps1

powershellhistory

6 comments

Extending PowerShell – Code Camp IV

For the fourth Twin Cities Code Camp I gave a presentation on Extending PowerShell for developers.  Turnout was great yet again at Code Camp, pretty much every session filled up.  The enthusiasm of the people who attend these sessions really make it a fun place to present.  I had a great group in my session, they helped make it into a very interactive presentation.

I started with scripting in PowerShell, then moved into dynamically adding members (properties and functions) to objects.  The PS1XML file is available for download.  Additionally, if you were interested in another example of this, the PowerShell for SharePoint Developers session I did at DevConnections has another good example of where a PS1XML can be used.

A Cmdlet and SnapIn were created using David Aiken‘s great PowerShell Visual Studio templates.  It demo’d passing parameters to a Cmdlet and having it return an array of items back to the Pipeline.  I also showed two implementations of hosting PowerShell; one for running a command from your app, and the other for replacing the UI entirely.

Slides
Code

No comments

Deleting SharePoint Site Alerts

A question came up on the #sharepoint Freenode IRC channel (join us) about how to easily delete all the alerts for a site.  He had come across this post about creating a web part to do exactly what he wanted.  However, since he is an administrator and the post requires creating and deploying a web part it seemed like a lot of extra work. Enter PowerShell.

The solution took the form of a simple 4 line PowerShell script:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$site = new-object Microsoft.SharePoint.SPSite("http://mydomain.com/someweb")
$web = $site.OpenWeb()
"I'd delete {0} alerts" -f $web.Alerts.Count #Only warns about deleting

If you pasted the code above into your environment (replacing the web URL with your own) it will tell you how many Alerts are associated with the site. If you really want to DELETE all of them, you can add the following line of code:

$web.Alerts|%{$web.Alerts.Delete($_.Id)} #Actually Deletes them!

Since you are already in PowerShell, there are a couple other interesting things you can do. You could filter for only the alerts in a single list:

$web.Alerts|?{$_.ListUrl -like "Documents"} #assumes http://mydomain.com/someweb/documents

Or you could find all the Alerts for a specific user across the web:

$web.Alerts|?{$_.UserId -like "DOMAIN\username"}

But wait, there’s more! If you wanted to see all the alerts for a user across the entire site collection:

$site.AllWebs|select -expand Alerts|?{$_.UserId -like "DOMAIN\username"}
No comments

DevConnections – PowerShell for SharePoint Developers

My final presentation at SharePoint Connections was the one I’d been looking forward to the most.  I’m a big fan of using PowerShell and SharePoint together, it was great to show a crowd some of the thing they could do.  I’d done a couple hour PowerShell presentations (that always seemed to run long) before, but never with SharePoint.  The challenge this time was to do them both together…in an hour.  I was able to get through everything I’d planned and now I have some more detailed content that didn’t fit into the presentation that I can put into some future posts.

The deck is now uploaded, and as promised, you didn’t miss out if you couldn’t write down all my commands.  Nearly all of the commands are here, incorrect statements and all.  I also have my profile, so you can see how I cheated in my other presentations.

I also made a basic PowerShell Types (ps1xml) file to demonstrate the how to extend familiar types to make them easier to work with.  You can grab the file and use it in your own development environment, though I probably wouldn’t rely on it in production quite yet.  Remember to get it started you need to:

Update-TypeData -prepend JustAddCode.Types.ps1xml

3 comments

Creating SharePoint’s SafeControl Entries in PowerShell

Manually adding a new assembly for anWebPart to SharePoint can be a hassle. I always hate tracking down the various parts of the SafeControl line to add to the web.config. If you’ve ever done this manually before, you know that the most time consuming part is finding the public key token My preferred way had been to use ‘sn.exe -T someAssembly.txt’, but in .NET 2.0 sn.exe was no longer included with the default install. Once again, PowerShell gave me a simple solution:

1
2
3
$assembly = [System.Reflection.Assembly]::LoadFile("c:\temp\TestWebPartLibrary.dll") 
$name = $assembly.GetName() 
"<SafeControl Assembly=""{0}"" Namespace=""{1}"" TypeName=""*"" />" -f $assembly.FullName,$assembly.GetName().Name

The first line loads a dll into PowerShell and stores the resulting System.Reflection.Assembly in a variable. The next line stores the results of Assembly.GetName() into a local variable we can use later. The final line similar to String.Format in .NET. $assembly.FullName outputs the entire value for Assembly we need, including that pesky public key token!  For the Namespace attribute, I’m just using the name of the assembly. This isn’t necessarily true in all cases, but I usually have the dll and namespace sharing the same name.

When running these three lines I get the following familiar result:

<SafeControl Assembly="TestWebPartLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=82a1533dcdde9e6a" Namespace="TestWebPartLibrary" TypeName="*" />

Since we’re now able to create the line for a single .dll, lets wrap it up in a function so we can get a bit more mileage out of it.

function get-safecontrolline($assemblyLocation) 
{
   $assembly = [System.Reflection.Assembly]::LoadFile($assemblyLocation)
   $name = $assembly.GetName()
   "<SafeControl Assembly=""{0}"" Namespace=""{1}"" TypeName=""*"" />" -f $assembly.FullName,$assembly.GetName().Name 
}

Now we can call it and pass in the file as an argument. Now its a snap to generate the SafeControl entries for an entire directory!

C:Temp > dir *.dll|%{get-safecontrolline($_) } 
<SafeControl Assembly="TestWebPartLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=82a1533dcdde9e6a" Namespace="TestWebPartLibrary" TypeName="*" /> 
<SafeControl Assembly="AnotherLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=82a1533dcdde9e6a" Namespace="AnotherLibrary" TypeName="*" />        

C:Temp >
3 comments

Virtual machine copying with PowerShell

Believe it or not, PowerShell is more than just fun and games. You can even do productive things with it! A common scenario I run into is the need to create a new virtual machine. Usually I want to base it on one I’ve already created and I want it to join a domain. There are a couple issues that I run in to:

  1. Duplicate SID Error
  2. Too many clicks

The first problem can be solved with a free tool that Microsoft has released called NewSID. Running that will give my virtual a unique SID so that it can be added to the domain.

Now for the second problem..too many clicks! Renaming a machine and adding it to the domain takes almost 2 minutes and a nearly infinite number of clicks and keystrokes…or maybe not. At any rate, it’d be great to simplify this process. Enter PowerShell.
Rename a Computer and Join Domain

$comp = get-wmiobject Win32_ComputerSystem 
$comp.Rename("newComputerName","password","administrator") 
$comp.JoinDomainOrWorkGroup("MYDOMAIN","domainPassword","MYDOMAIN\domainAdmin",$null,3)

Add a call to NewSID, wrap those delicious lines in a function and you are well on your way to renaming a virtual and joining a domain in fewer keystrokes. Its so easy you might even find yourself creating new virtuals just to run it again.

5 comments