Bookmark and Share 

 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I am primarily a database guy, but I have started using Windows PowerShell because of the Windows PowerShell cmdlets for SQL Server 2008. One thing I like about databases is that I can create a transaction. For example, I can begin a transaction, transfer money from one account to another account, check that the transfer completed properly, and then delete the money from the original account. If the transfer does not complete properly, I roll back the transaction and make no changes. I wish I could do something like that in Windows PowerShell.

-- TL

 

Hey, Scripting Guy! AnswerHello TL,

Microsoft Scripting Guy Ed Wilson here. Your e-mail message brings up a conversation I had with the Scripting Wife many years ago when we were getting ready to leave for Kauai, Hawaii. She went online to our bank to transfer some funds from savings to checking so that we would have more direct access to cash if we needed it (we did; Hawaii is expensive when you come from the southern United States). Because this was a long time ago, the Scripting Wife was not as Internet savvy as she is today. The Internet connection to our bank’s Web site failed in the process of moving the money, and she began to panic.

At that time, I was doing a lot of database work and had even taught several SQL Server certification classes at the local Microsoft Training Center. I calmly explained to her about the ACID principle that governs transactional database operations and exclaimed that we would simply check our account balances when we arrived in Lihue. If the bank’s database team was so lame as to not follow such a basic principle, we would be changing banks. The bank was smart enough to initiate a transaction at the beginning of the operation, and because the Internet connection failed before completion, the transaction rolled back and the money was still in the savings account.

The following picture of a honu is one that I took while scuba diving during that trip.

Image of a honu

 

TL, the first thing you need to know about using transactions in Windows PowerShell 2.0 is that it requires you to be running a minimal operating system version. The minimum operating system version that supports transactions is Windows Vista. Unfortunately, you can start a transaction on Windows XP, but Windows PowerShell does not generate an error until you attempt to use the transaction. The following image illustrates this.

Image of error generated by Windows PowerShell

 

The next thing you need to know about using transactions in Windows PowerShell 2.0 is that the provider must support transactions. Before you check for transaction support, you may wish to load any modules you may have installed. Windows PowerShell 2.0 ships with several default modules, and other modules are available for download from CodePlex and other places. In addition, we have been writing our own module during the Weekend Scripter series. To see which modules are loaded, use the Get-Module cmdlet. To see available modules, use the Get-Module cmdlet with the –listavailable parameter. The code list that follows illustrates this:

PS C:\> Get-Module
PS C:\> Get-Module -ListAvailable

ModuleType Name                      ExportedCommands
---------- ----                      ----------------
Script     BasicFunctions            {}
Script     ConversionModuleV4        {}
Script     DotNet                    {}
Manifest   FileSystem                {}
Manifest   IsePack                   {}
Manifest   PowerShellPack            {}
Manifest   PSCodeGen                 {}
Manifest   PSImageTools              {}
Manifest   PSRSS                     {}
Manifest   PSSystemTools             {}
Manifest   PSUserTools               {}
Manifest   TaskScheduler             {}
Manifest   WPK                       {}
Manifest   ActiveDirectory           {}
Manifest   AppLocker                 {}
Manifest   BitsTransfer              {}
Manifest   FailoverClusters          {}
Manifest   GroupPolicy               {}
Manifest   NetworkLoadBalancingCl... {}
Manifest   PSDiagnostics             {}
Manifest   TroubleshootingPack       {}


After you have found your list of available modules, you may wish to load all of the modules at once. You can do this by piping the results of your Get-Module –Listavailable command to the Import-Module cmdlet. Use the Get-Module cmdlet to ensure that the modules import properly. The command seen here illustrates this technique:

PS C:\> Get-Module -ListAvailable | Import-Module
PS C:\> Get-Module

ModuleType Name                      ExportedCommands
---------- ----                      ----------------
Script     BasicFunctions            {Get-ComputerInfo, Get-OptimalSize}
Script     ConversionModuleV4        {ConvertTo-Feet, ConvertTo-Miles, ConvertTo-Pounds, ConvertTo-Meters...}
Script     PowerShellPack            {New-ByteAnimationUsingKeyFrames, New-TiffBitmapEncoder, New-Viewbox, Ne...
Script     PSCodeGen                 {New-Enum, New-ScriptCmdlet, New-PInvoke}
Script     PSImageTools              {Add-CropFilter, Add-RotateFlipFilter, Add-OverlayFilter, Set-ImageFilte...
Script     PSRss                     {Read-Article, New-Feed, Remove-Article, Remove-Feed...}
Script     PSSystemTools             {Test-32Bit, Get-USB, Get-OSVersion, Get-MultiTouchMaximum...}
Script     PSUserTools               {Start-ProcessAsAdministrator, Get-CurrentUser, Test-IsAdministrator, Ge...
Script     TaskScheduler             {Remove-Task, Get-ScheduledTask, Stop-Task, Add-TaskTrigger...}
Script     WPK                       {Get-DependencyProperty, New-ModelVisual3D, New-DiscreteVector3DKeyFrame...
Manifest   ActiveDirectory           {Set-ADOrganizationalUnit, Get-ADDomainControllerPasswordReplicationPoli...
Manifest   AppLocker                 {Get-AppLockerPolicy, Get-AppLockerFileInformation, Test-AppLockerPolicy...
Manifest   BitsTransfer              {Start-BitsTransfer, Remove-BitsTransfer, Resume-BitsTransfer, Get-BitsT...
Manifest   FailoverClusters          {Set-ClusterParameter, Get-ClusterParameter, Stop-ClusterNode, Stop-Clus...
Manifest   GroupPolicy               {Get-GPStarterGPO, Get-GPOReport, Set-GPInheritance, Restore-GPO...}
Manifest   NetworkLoadBalancingCl... {Stop-NlbClusterNode, Remove-NlbClusterVip, New-NlbClusterIpv6Address, S...
Script     PSDiagnostics             {Enable-PSTrace, Enable-WSManTrace, Start-Trace, Disable-PSWSManCombined...
Manifest   TroubleshootingPack       {Get-TroubleshootingPack, Invoke-TroubleshootingPack}


Now that you have imported all of your modules, use the Get-PSProvider cmdlet to see which Windows PowerShell providers support transactions. This is shown here:

PS C:\> Get-PSProvider

Name                 Capabilities                                      Drives
----                 ------------                                      ------
WSMan                Credentials                                       {WSMan}
Alias                ShouldProcess                                     {Alias}
Environment          ShouldProcess                                     {Env}
FileSystem           Filter, ShouldProcess                             {C, E, Desktop, Programs...}
Function             ShouldProcess                                     {Function}
Registry             ShouldProcess, Transactions                       {HKLM, HKCU}
Variable             ShouldProcess                                     {Variable}
Certificate          ShouldProcess                                     {cert}
ActiveDirectory      Include, Exclude, Filter, ShouldProcess, Crede... {}


The capabilities of the ActiveDirectory provider are truncated. To see all of the capabilities of the ActiveDirectory provider, pipe the results to Format-List (fl is the alias), as shown here:

PS C:\> Get-PSProvider act* | fl capabilities


Capabilities : Include, Exclude, Filter, ShouldProcess, Credentials


It would seem that the only provider that supports transactions is the registry provider. To make certain of our results, we can use the Where-Object cmdlet (? Is the alias) to filter out the results obtained by the Get-PSProvider cmdlet, as shown here:

PS C:\> Get-PSProvider | Where-Object { $_.capabilities -match 'transactions'}

Name                 Capabilities                                      Drives
----                 ------------                                      ------
Registry             ShouldProcess, Transactions                       {HKLM, HKCU}

 

TL, that is all there is to understanding transactions in Windows PowerShell. Tomorrow, we will continue working with transactions.

If you want to know exactly what we will be looking at tomorrow, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys