Weekend Scripter: Playing Around with PowerShell Namespace ApartmentState

Weekend Scripter: Playing Around with PowerShell Namespace ApartmentState

  • Comments 4
  • Likes

Summary: Microsoft Scripting Guy, Ed Wilson, talks about exploring the Windows PowerShell namespace ApartmentState property.

Microsoft Scripting Guy, Ed Wilson, is here. Ah, it is the weekend. It is not that I “live for weekends” or anything like that. It is just that weekends are different. I generally spend more time preparing my breakfast—Irish steel-cut oats are not out of the question (and it takes me a good 45 minutes to cool steel-cut oats). I take extra care in preparing just the right pot of tea to suit my mood, and I spend long hours playing around with Windows PowerShell—often with no preconceived results in mind. I just want to play, explore, and learn. During the week, I always have a plan—I know what the next 20 Hey, Scripting Guy! Blog posts will be. I always work towards a plan. No so on the weekend. 

Windows PowerShell 3.0 console

Did you know that in Windows PowerShell 3.0, we changed the Windows PowerShell console from multi-threaded apartment (MTA) to single-threaded apartment (STA)? If you did not notice the change, you are probably not doing anything that requires MTA mode. If all of a sudden, you have some Windows PowerShell 2.0 or even Windows PowerShell 1.0 scripts that no longer work, now you know why.

Note   If you need a refresher on apartment models, refer to Apartments and Pumping in the CLR on Chris Brumme’s blog.

The Windows PowerShell 2.0 defaults were the Windows PowerShell ISE opened in STA mode, and the Windows PowerShell console opened in MTA mode. In Windows PowerShell 3.0, both the Windows PowerShell console and the Windows PowerShell ISE open in STA mode. By returning the Runspace property from the $host automatic variable, I obtained useful information about the Runspace. The following command shows this.

$host.Runspace

The command and associated output from the command are shown in the following image.

Image of command output

I can pick up the host name as well as the ApartmentState directly. This technique is shown here.

15:42 C:\> $host.name

ConsoleHost

15:42 C:\> $host.Runspace.ApartmentState

STA

In the Windows PowerShell ISE, the following results are shown.

PS C:\> $host.Name

Windows PowerShell ISE Host

 

PS C:\> $host.Runspace.ApartmentState

STA

The Runspace property returns a LocalRunSpace object. The members of this object are shown here.

15:45 C:\> $host.Runspace | gm

   TypeName: System.Management.Automation.Runspaces.LocalRunspace

Name                         MemberType Definition

----                         ---------- ----------

AvailabilityChanged          Event      System.EventHandler`1[System.Management.A...

StateChanged                 Event      System.EventHandler`1[System.Management.A...

ClearBaseTransaction         Method     void ClearBaseTransaction()

Close                        Method     void Close()

CloseAsync                   Method     void CloseAsync()

Connect                      Method     void Connect()

ConnectAsync                 Method     void ConnectAsync()

CreateDisconnectedPipeline   Method     System.Management.Automation.Runspaces.Pi...

CreateDisconnectedPowerShell Method     powershell CreateDisconnectedPowerShell()

CreateNestedPipeline         Method     System.Management.Automation.Runspaces.Pi...

CreatePipeline               Method     System.Management.Automation.Runspaces.Pi...

Disconnect                   Method     void Disconnect()

DisconnectAsync              Method     void DisconnectAsync()

Dispose                      Method     void Dispose(), void IDisposable.Dispose()

Equals                       Method     bool Equals(System.Object obj)

GetApplicationPrivateData    Method     psprimitivedictionary GetApplicationPriva...

GetCapabilities              Method     System.Management.Automation.Runspaces.Ru...

GetHashCode                  Method     int GetHashCode()

GetType                      Method     type GetType()

Open                         Method     void Open()

OpenAsync                    Method     void OpenAsync()

ResetRunspaceState           Method     void ResetRunspaceState()

SetBaseTransaction           Method     void SetBaseTransaction(System.Transactio...

ToString                     Method     string ToString()

ApartmentState               Property   System.Threading.ApartmentState Apartment...

ConnectionInfo               Property   System.Management.Automation.Runspaces.Ru...

Debugger                     Property   System.Management.Automation.Debugger Deb...

Events                       Property   System.Management.Automation.PSEventManag...

InitialSessionState          Property   System.Management.Automation.Runspaces.In...

InstanceId                   Property   guid InstanceId {get;}

JobManager                   Property   System.Management.Automation.JobManager J...

LanguageMode                 Property   System.Management.Automation.PSLanguageMo...

OriginalConnectionInfo       Property   System.Management.Automation.Runspaces.Ru...

RunspaceAvailability         Property   System.Management.Automation.Runspaces.Ru...

RunspaceConfiguration        Property   System.Management.Automation.Runspaces.Ru...

RunspaceStateInfo            Property   System.Management.Automation.Runspaces.Ru...

SessionStateProxy            Property   System.Management.Automation.Runspaces.Se...

ThreadOptions                Property   System.Management.Automation.Runspaces.PS...

Version                      Property   version Version {get;}

The Runspace object is documented on MSDN. This means, that if I wish, I can access the same information via the .NET Framework. This technique is shown here.

15:48 C:\> [System.Management.Automation.Runspaces.runspace]::DefaultRunspace.Apartme

ntState

STA

Hey, I don’t know about you, but for me, I prefer to access the information via $host (although keep in mind that tab expansion does work for these types of things now).

Oh well, I am off to do some other stuff on this fine PowerShell day. Join me tomorrow for an article from the Scripting Wife about the Winter 2013 Scripting Games. Yes, if you don’t know, they are going on right now.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Ed - Thanks for this blog. Coming from a SharePoint PowerShell perspective, having the shell default to STA is great as so many objects in the SharePoint stack are not thread safe. Often times in the field I see folks loading the Microsoft.SharePoint.PowerShell snappin in the PowerShell 2.0 console and executing scripts (instead of using the SharePoint Management Shell which defaults to STA) not realizing that the default is MTA which could cause issues. With PowerShell 3.0, defaulting to STA is a welcome change for the SharePoint crowd.

    Cheers,

    Craig

  • Just one more comment - if a script or function is executed from a single line in PowerShell, it is executed in a single thread even in MTA mode. So for those in the SharePoint space, if you are calling a function/script from a single line in the PowerShell 2.0 console (i.e. not the SharePoint Management Shell), the entirety of the script/function is executed as a single thread and therefore thread safe so long as all pipeline operations are completed on the same line (thread).

    Ed, if you have anything to add to this please do.

    Cheers,

    Craig

  • @Craig Lussier - yes changing PowerShell to STA mode by default in fact helps to avoid a lot of confusion, and for most things does not really hamper backward compatibility either.

    @Craig Lussier - I have done very little with SharePoint, and even less with specific SharePoint scripting so I am not the best person to comment on this. But thanks for sharing the insights.

  • By the way, if you launch Windows PowerShell in 2.0 mode by using: powershell -version 2 then PowerShell also starts in MTA mode.