Subscribe: PowerShell
Preview: PowerShell


Microsoft Windows PowerShell

Copyright: Lance Robinson

Creating Team Foundation Work Items With PowerShell

Wed, 26 Jan 2011 15:58:22 GMT

Originally posted on:

Here is the simple function I added to my powershell profile:




function create-tfstask ($desc) {
 tfpt workitem /new $workItemType /collection:$serverUrl /fields:"Title=$($desc);Assigned To=$assignee;AreaId=$areaId;IterationId=$iterationId"



To find the AreaId and IterationId for your project/versions, just look at a bug you know is setup correctly:

PS C:\> tfpt query /collection:http://3bs001vsteam:8080/tfs /wiql:"select AreaId,IterationId from workitems where ID = 879"

Next I hooked this into my existing "todo" function by adding a new case in its $target switch statement for “tfs”, which calls my create-tfstask function and returns.  Updated todo function:

function todo {
  param([string] $target = "work",
        [string] $msg )
  $emailFrom = ""
  #combine all the cmd line args into one "message"
  if ($args -ne "") {
    $msg = $msg + " " + $args
  #what is the target of the message?
  switch ($target)
    "work" { $target = "" }
    "home" { $target = "" }
    "tfs" { create-tfstask $msg; return }
  $subject = "Todo: " + $msg
  $body = $msg
  $smtpServer = "3bs001exch"	
  $smtp = new-object Net.Mail.SmtpClient($smtpServer, 25)
  $smtp.Send($emailFrom, $target, $subject, $body)
Technorati Tags: ,,

PowerShell – Recycle All IIS App Pools

Thu, 16 Dec 2010 20:59:17 GMT

Originally posted on:

With a little help from Shay Levy’s post on Stack Overflow and the MSDN documentation, I added this handy function to my profile to automatically recycle all IIS app pools.

function Recycle-AppPools {
    [string] $server = "3bhs001",
    [int] $mode = 1, # ManagedPipelineModes: 0 = integrated, 1 = classic

 $iis = [adsi]"IIS://$server/W3SVC/AppPools"
$iis.psbase.children | %{
$pool = [adsi]($_.psbase.path);
   if ($pool.AppPoolState -eq 2 -and $pool.ManagedPipelineMode -eq $mode) {
   # AppPoolStates:  1 = starting, 2 = started, 3 = stopping, 4 = stopped         





Upcoming conferences: Etech, MMS, Web 2.0

Tue, 20 Mar 2007 13:26:00 GMT

Originally posted on:

/n software will be at several upcoming conferences, including the O'Reilly Emerging Technology Conference, the Microsoft Management Summit, and the Web 2.0 Expo. If you will be there, stop by and say "Hi!".


PowerShell book

Tue, 27 Feb 2007 16:46:00 GMT

Originally posted on:

Bruce Payette's Windows Powershell in Action (image) is now available on Amazon.


Quick PowerShell “Todo” Gmail Emailer

Tue, 26 Oct 2010 17:27:13 GMT

Originally posted on: put the following function in my PowerShell profile so that I can just bring up my PowerShell console and type myself a quick “todo” note that automatically gets emailed to me for later.  There are several things of note in this tiny script: 1.  Note the use of the $args variable to effectively allow the user to enter $msg parameter without quotes even if it contains whitespace. 2.  In this particular example I’m sending the email through Gmail., port 587, SSL and authentication required. 3.  Check outhe $gmailcred variable, which gets set earlier in my profile.  It gets read from a secure string file.             function todo { param([string] $target = "work", [string] $msg ) switch ($target) { "work" { $target = "" } "home" { $target = "" } } $emailFrom = "" if ($args -ne "") { $msg = $msg + " " + $args } $subject = "Todo: " + $msg $body = $msg $smtpServer = "" $smtp = new-object Net.Mail.SmtpClient($smtpServer, 587) $smtp.EnableSsl = $true $smtp.Credentials = [Net.NetworkCredential]($gmailcred) $smtp.Send($emailFrom, $target, $subject, $body) }       Technorati Tags: PowerShell,Gmail,Parameters [...]

PowerShell TruncateAtWhitespace Function

Mon, 16 Aug 2010 19:30:13 GMT

Originally posted on:’s a TruncateAtWhitespace function that takes an incoming parameter value and an incoming max length, and returns a substring broken at a whitespace position.  This way if you have “Lance has a blog” and you need to truncate it to 8 characters or less, you get “Lance” instead of “Lance ha”. function TruncateAtWhitespace{ param( [string]$value, [int]$maxlength=200 ) $maxlength-=3; #allow for "..." suffix if ($value.Length -le $maxlength) { return ($value + "..."); } $closestwhitespaceindex = [int]$value.Substring(0, $maxlength).LastIndexOf(" "); if ($closestwhitespaceindex -gt 0) { $value = $value.Substring(0, $closestwhitespaceindex) + "..."; } else { $value = $value.Substring(0, $maxlength); } return $value; } Technorati Tags: PowerShell [...]

Exception setting "ThreadOptions" in SharePoint 2010 Management Shell

Wed, 17 Feb 2010 18:56:51 GMT

Originally posted on:

Right after you install SP2010 (Foundation or Server), even on a completely updated Windows Server 2008 SP2, when you go to start the SharePoint 2010 Management Shell (the recommended PowerShell interface for working with SharePoint), you get a real ugly looking error:

Exception setting "ThreadOptions": "This property cannot be changed after the Runspace has been opened."
At C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONF
IG\POWERSHELL\Registration\SharePoint.ps1:2 char:48
+ if ($ver.Version.Major -gt 1)  {$Host.Runspace. <<<< ThreadOptions = "ReuseTh
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyAssignmentException

To get around this problem, update the Windows Management Framework Core.  See KB968930, where you can download updates for various versions of Windows.



PowerShell: Twitter Auto UN-follow

Tue, 12 Jan 2010 18:06:00 GMT

Originally posted on: who uses Twitter has heard of auto-follow services for Twitter. Below is a PowerShell script I used to auto UNfollow.  The script goes through the people you're following and eliminates "idle" or "spam" friends.  An idle friend is determined by a low friend count or low status count on an account that has been in existance for at least a couple months (configurable).  A spam friend is determined by a high friend count but a low follower count (by default, the script uses a 15-1 ratio as the max). I would appreciate any good tweaks or improvements you might like to share!  In particular I wasn't sure how to deal with Twitter's rate limiting (150 get requests per hour).  For now I just catch the exception when it occurs and sleep for an hour before resuming.           #this script goes through the people you're following and eliminates "idle" or "spam" friends. #an idle friend is determined by low friends or statuses on an account that has been in existance for a while #a spam friend is determined by high friends but low followers param([int] $minfriends = 20, [int] $minstatuses = 20, [int] $minaccountage = 60, #days [int] $maxratio = 15, [switch] $silent = $false #whether or not to prompt before unfollowing ) function unfollow($userid, $userinfo) { do { Write-Host "Unfollowing User $($userinfo.user.screen_name): $($userinfo.user.friends_count) friends/$($userinfo.user.followers_count) followers/$($userinfo.user.statuses_count) statuses [y/n/l]: " -noNewLine -foregroundColor Yellow if ($silent -eq $false) { $cmd = Read-Host } if ($silent -eq $true -or $cmd -eq "y") { $wc = new-object net.webclient $wc.Credentials = $global:twittercred $unfollo = $wc.UploadString("$($userid).xml", "") $unfollow.user.following } if ($cmd -eq "l") { Start-Process "$($userinfo.user.screen_name)" } } while ($silent -eq $false -and $cmd -eq "l") } #enter your Twitter credentials for retrieving your friends list $global:twittercred = Get-Credential #retrieve the full friends list $wc = new-object net.webclient $wc.Credentials = $global:twittercred $response = [xml]($wc.DownloadString("")) #now loop through each friend $ | % { try { #get detailed info about this user $showuser = [xml]($wc.DownloadString("$($_)")) } catch { Write-Host "Twitter rate limit reached (150 gets/hour). Pausing for one hour..." -foregroundColor Red -noNewLine Start-Sleep -Seconds 3600 } #determine if they are worthy of following: $datecreated = [DateTime]::ParseExact($showuser.user.created_at, "ddd MMM dd H:mm:ss +0000 yyyy", [System.Globalization.CultureInfo]::InvariantCulture) $accountage = ([DateTime]::Now).Subtract($datecreated).Days $statusescount = [int]$showuser.user.statuses_count $friendscount = [int]$showuser.user.friends_count $followerscount = [int]$showuser.user.followers_count if (($accountage -ge $minaccountage) -and ($friendscount -lt $minfriends -or $statusescount -lt $minstatuses)) { #unfollow idle friends: unfollow $_ $showuser } elseif (($accountage -ge $minaccountage -and $followerscount -eq 0) -or ($followerscount -gt 0 -and $friendscount / $followerscount -gt $maxratio)) { #unfollow spam friends: unfollow $_ $showuser } else { Write-Host "Good friend $($showuser.user.screen_name): $($friendscount)/$($friendscount)/$($statusesco[...]

Program Files Environment Variable in PowerShell

Tue, 29 Dec 2009 12:27:08 GMT

Originally posted on:

Today I saw this on Twitter from Julie Blender (@#juneb_get_help): 

Need to reference the "ProgramFiles(x86)" environment variable in #PowerShell? Use ${env:ProgramFiles(x86)}.

I use this in a lot of my scripts, but I want a single variable that contains the right value whether I'm in a 64 bit shell or not.  Here's my solution:

First, I have a function in my testing profile called is64bit, that looks like this:

function is64bit() {
  return ([IntPtr]::Size -eq 8)

Next, I have a get-programfilesdir function that I call that checks whether or not I'm in a 64 bit shell or not and returns the appropriate program files environment variable (ie, if I'm running on a 64 bit machine it will return "C:\Program Files (x86)", but if I'm running on a 32 bit machine it will return "C:\Program Files".  If I'm running in a 32 or 64 bit shell on a 64 bit machine, it will always return "C:\Program Files (x86)".

function get-programfilesdir() {
  if (is64bit -eq $true) {
    (Get-Item "Env:ProgramFiles(x86)").Value
  else {
    (Get-Item "Env:ProgramFiles").Value


Technorati Tags:

10 PowerShell One Liners

Tue, 29 Dec 2009 09:36:37 GMT

Originally posted on: are a few one-liners that use NetCmdlets. Some of these I've blogged about before, some are new. Let me know if you have questions, which ones you find useful, or how you altered these to suit your own needs. Send email to a list of recipient addresses: import-csv users.csv | % { send-email -to $ -from -subject "Important Email" –message "Hello World!" -server } Show the access control list for a specific Exchange folder: get-imap -server $mymailserver -cred $mycred -folder INBOX.RESUMES –acl Add look and read permissions on an Exchange folder, for a list of accounts pulled from a CSV file: import-csv users.csv | % { set-imap -server -acluser $_.username $mymailserver -cred $mycred -folder INBOX.RESUMES –acl “lr”  } Sync system time with an Internet time server: get-time -server –set To remotely sync the time on a set of computers: import-csv computers.csv | % { Invoke-Command -computerName $ -cred $mycred -scriptblock { get-time -server –set } } Delete all emails from an Exchange folder that match a certain criteria.  For example, delete all emails from get-imap -server $mailserver –cred $mycred | ? {$_.FromEmail -eq} | %{ set-imap -server $mailserver –cred $mycred-message $_.Id -delete } Update Twitter status from PowerShell: get-http –url "" –cred $mycred -variablename status -variablevalue "Tweeting with NetCmdlets!" A test-path that works over FTP, FTPS (SSL), and SFTP (SSH) connections: get-ftp -server $remoteserver –cred $mycred -path /remote/path/to/checkfor* Don't forget the *.  Also, to use SSL or SSH just add an –ssl or –ssh parameter. List disabled user accounts in Active Directory (or any other LDAP server): get-ldap -server $ad -cred $mycred -dn dc=yourdc -searchscope wholesubtree     -search "(&(objectclass=user)(objectclass=person)(company=*)(userAccountControl:1.2.840.113556.1.4.803:=2))" List Active Directory groups and their members: get-ldap -server testman -cred $mycred -dn dc=NS2 -searchscope wholesubtree -search "(&(objectclass=group)(cn=*admin*))" | select ResultDN, member Display the last initialization time (e.g. last reboot time) of all discoverable SNMP agents on a network: import-csv computers.csv | % { get-snmp -agent $ -oid sysUpTime.0 | %{([datetime]::Now).AddSeconds(-($_.OIDValue/100))} } Not mentioned here:  data conversion (Yenc, QP, UUencoding, MD5, SHA1, base64, etc), DNS, News Groups (NNTP/UseNet), POP mail, RSS feeds, Amazon S3, Syslog, TFTP, TraceRoute, SNMP Traps, UDP, WebDAV, whois, Rexec/Rshell/Telnet, Zip files, sending IMs (Jabber/GoogleTalk/XMPP), sending text messages and pages, ping, and more.   Technorati Tags: PowerShell,NetCmdlets,Active Directory,Exchange,Oneliners [...]