{"id":6221,"date":"2008-05-08T19:02:00","date_gmt":"2008-05-08T19:02:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2008\/05\/08\/powershell-transactions-quickstart\/"},"modified":"2019-02-18T13:15:58","modified_gmt":"2019-02-18T20:15:58","slug":"powershell-transactions-quickstart","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/powershell-transactions-quickstart\/","title":{"rendered":"PowerShell Transactions QuickStart"},"content":{"rendered":"<p class=\"MsoNormal\">The second CTP of PowerShell V2 (CTP2) introduces full engine support for transactions \u2013 groups of actions that can be finalized or undone in an all-or-nothing way. Wikipedia gives a great overview of transactions here: <a href=\"http:\/\/en.wikipedia.org\/wiki\/Database_transactions\">http:\/\/en.wikipedia.org\/wiki\/Database_transactions<\/a>.<\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\">We put a ton of thought into how to expose this normally developer-centric concept in a way suitable for system administration and system administrators. We would LOVE to hear your feedback on what concepts or behaviours make sense, and especially which ones do not.<\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\">We didn\u2019t get a chance to fully document these cmdlets in the CTP2, though, so here\u2019s a quick start and primer to help you explore the feature.<\/p>\n<h3><span>&nbsp;<\/span><\/h3>\n<h3><font face=\"Arial Black\" size=\"3\">Using transactions<\/font><\/h3>\n<p class=\"MsoBodyText\">PowerShell surfaces its support for transactions through the following cmdlets:<\/p>\n<p class=\"MsoBodyText\"><span>PS C:\\Temp&gt; gcm *transaction*<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>CommandType<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Name<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&#8212;&#8212;&#8212;&#8211;<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;-<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Cmdlet<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Complete-PSTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Completes \/ Commits a transaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Cmdlet<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Start-PSTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Begins a transaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Cmdlet<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Undo-PSTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Rolls back a transaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Cmdlet<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Use-PSTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Places the current PowerShell transaction in Transaction.Current, for direct .NET Scripting against transacted objects.<\/span><\/p>\n<p class=\"MsoBodyText\">&nbsp;<\/p>\n<p class=\"MsoBodyText\">To start a transaction, call the Start-PSTransaction cmdlet. To use a cmdlet that supports transactions, call it with the <span>\u2013UseTransaction<\/span> parameter. Being explicit about this parameter is crucial, as many cmdlets that support transactions can work equally well without one. Because of that, PowerShell only surfaces the transaction to the cmdlet when you supply this parameter.<\/p>\n<p class=\"MsoBodyText\">PowerShell\u2019s registry provider supports transactions on Vista. In addition, a utility class called <span>System.Management.Automation.TransactedString<\/span> supports transactions on all platforms.<\/p>\n<p class=\"MsoBodyText\">Once you have completed the transactional work, call the Complete-PSTransaction cmdlet to make it final, or the Undo-PSTransaction cmdlet to discard the changes.<\/p>\n<p class=\"MsoBodyText\">&nbsp;<\/p>\n<p class=\"MsoBodyText\">Here is an example session that illustrates these concepts:<\/p>\n<p class=\"MsoBodyText\"><span>PS C:\\Users\\leeholm&gt; cd hkcu:\\temp<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; dir<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; Start-PsTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## Create a key. We didn\u2019t specify the \u2013UseTransaction parameter, so it is not being done in a transaction.<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; New-Item WillStayBehind<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp;&nbsp; <\/span>Hive: Microsoft.PowerShell.Core\\Registry::HKEY_CURRENT_USER\\temp<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>SKC<span>&nbsp; <\/span>VC Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Property<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&#8212;<span>&nbsp; <\/span>&#8212; &#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp; <\/span>0<span>&nbsp;&nbsp; <\/span>0 WillStayBehind<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## Create a key in the transaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; New-Item WillGetRolledBack -UseTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp;&nbsp; <\/span>Hive: Microsoft.PowerShell.Core\\Registry::HKEY_CURRENT_USER\\temp<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>SKC<span>&nbsp; <\/span>VC Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Property<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&#8212;<span>&nbsp; <\/span>&#8212; &#8212;- <span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>&#8212;&#8212;&#8211;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp; <\/span>0<span>&nbsp;&nbsp; <\/span>0 WillGetRolledBack<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## Get-ChildItem from outside of the transaction. You don\u2019t see any of your transacted changes.<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; Get-ChildItem<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp;&nbsp; <\/span>Hive: Microsoft.PowerShell.Core\\Registry::HKEY_CURRENT_USER\\temp<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>SKC<span>&nbsp; <\/span>VC Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Property<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&#8212;<span>&nbsp; <\/span>&#8212; &#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp; <\/span>0<span>&nbsp;&nbsp; <\/span>0 WillStayBehind<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## Get-ChildItem from inside of the transaction. Your transacted changes are now visible.<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; Get-ChildItem -UseTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp;&nbsp; <\/span>Hive: Microsoft.PowerShell.Core\\Registry::HKEY_CURRENT_USER\\temp<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>SKC<span>&nbsp; <\/span>VC Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Property<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&#8212;<span>&nbsp; <\/span>&#8212; &#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp; <\/span>0<span>&nbsp;&nbsp; <\/span>0 WillStayBehind<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp; <\/span>0<span>&nbsp;&nbsp; <\/span>0 WillGetRolledBack<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## Now, some transacted .NET scripting against the TransactedString object<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; $transactedString = New-Object System.Management.Automation.TransactedString<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; $transactedString.Append(&#8220;Hello &#8220;)<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## Append some text in the transaction. <\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; Use-PsTransaction -UseTransaction { $transactedString.Append(&#8220;World&#8221;) }<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## From outside the transaction, the changes are not visible<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; $transactedString.ToString()<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Hello<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## But from within the transaction, they are<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; Use-PsTransaction -UseTransaction { $transactedString.ToString() }<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Hello World<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## Roll back the transaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; Undo-PsTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>## Look at the registry, and only our non-transacted changes are there.<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; Get-ChildItem<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp;&nbsp; <\/span>Hive: Microsoft.PowerShell.Core\\Registry::HKEY_CURRENT_USER\\temp<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>SKC<span>&nbsp; <\/span>VC Name<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Property<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&#8212;<span>&nbsp; <\/span>&#8212; &#8212;-<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8212;&#8212;&#8211;<\/span><\/p>\n<p class=\"MsoBodyText\"><span><span>&nbsp; <\/span>0<span>&nbsp;&nbsp; <\/span>0 WillStayBehind<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>{}<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; Get-ChildItem -UseTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Get-ChildItem : Cannot use transaction. No transaction has been started.<\/span><\/p>\n<p class=\"MsoBodyText\"><span>At line:1 char:14<\/span><\/p>\n<p class=\"MsoBodyText\"><span>+ Get-ChildItem &lt;&lt;&lt;&lt;<span>&nbsp; <\/span>-UseTransaction<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt; $transactedString.ToString()<\/span><\/p>\n<p class=\"MsoBodyText\"><span>Hello<\/span><\/p>\n<p class=\"MsoBodyText\"><span>PS HKCU:\\temp&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<h3><font face=\"Arial Black\" size=\"3\">Developing for transactions \u2013 Cmdlet and Provider declarations<\/font><\/h3>\n<p class=\"MsoBodyText\">Cmdlets declare their support for transactions in a similar way that they declare their support for ShouldProcess:<\/p>\n<p class=\"MsoBodyText\">[Cmdlet(\u201cGet\u201d, \u201cProcess\u201d, SupportsTransactions=True)]<\/p>\n<p class=\"MsoBodyText\">&nbsp;<\/p>\n<p class=\"MsoBodyText\">Providers declare their support for transactions through the ProviderCapabilities flag:<\/p>\n<p class=\"MsoBodyText\">[CmdletProvider(\u201cRegistry\u201d, ProviderCapabilities.Transactions)]<\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<h3><font face=\"Arial Black\" size=\"3\">Developing for transactions \u2013 Participating in the PowerShell transaction<\/font><\/h3>\n<p class=\"MsoBodyText\">The PowerShell engine exposes transactions in a way that lets developers implement a transacted provider or cmdlet in the same way that they implement other transacted code.<\/p>\n<p class=\"MsoBodyText\">The recommended pattern for developing isolated transacted code in traditional applications is this: <a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms229973.aspx\"><font color=\"#0000ff\">http:\/\/msdn2.microsoft.com\/en-us\/library\/ms229973.aspx<\/font><\/a><\/p>\n<p class=\"MsoNormal\"><span>using(TransactionScope scope = new TransactionScope())<\/span><\/p>\n<p class=\"MsoNormal\"><span>{<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp; <\/span>&#8230; \/\/ Perform transactional work here<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp; <\/span>\/\/ No errors &#8211; commit transaction<br \/><span>&nbsp;&nbsp; <\/span>scope.Complete();<\/span><\/p>\n<p class=\"MsoNormal\"><span>}<\/span><\/p>\n<p class=\"MsoBodyText\">&nbsp;<\/p>\n<p class=\"MsoBodyText\">This is called implicit transaction management, and the code in the code block represents the entirety of the transacted operation. The TransactionScope object handles management of the ambient transaction, committing and rolling it back as necessary.<\/p>\n<p class=\"MsoBodyText\">Since cmdlet and provider developers should not deal directly with transaction scopes (but still be able to easily port transacted code,) PowerShell gives a similar experience:<\/p>\n<pre><span><font><font face=\"Courier New\">using(CurrentPsTransaction)<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\">{<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\"><span>&nbsp;&nbsp; <\/span>... \/\/ Perform transactional work here<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\">}<\/font><\/font><\/span><\/pre>\n<p class=\"MsoBodyText\">&nbsp;<\/p>\n<p class=\"MsoBodyText\">The CurrentPsTransaction property returns an IDisposable object. This IDisposable object, through the System.Transactions explicit programming model (<a href=\"http:\/\/msdn2.microsoft.com\/en-us\/library\/ms172146.aspx\"><font color=\"#0000ff\">http:\/\/msdn2.microsoft.com\/en-us\/library\/ms172146.aspx<\/font><\/a>), sets the current ambient transaction to be the current PowerShell Transaction. Its dispose method restores the previous ambient transaction. Attempting to use this current transaction while no transactions are active generates an error. The other transaction cmdlets control the nesting and lifetime of these transactions.<\/p>\n<p class=\"MsoBodyText\">This CurrentPsTransaction experience differs from the C# TransactionScope experience in two ways:<\/p>\n<p class=\"MsoBodyText\"><span><span>1)<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span>The object returned by the CurrentPsTransaction property does not actually represent a transaction. It does not support a Complete() method, Rollback() method, or anything else. The user is in charge of these decisions, not the cmdlet or provider developer.<\/p>\n<p class=\"MsoBodyText\"><span><span>2)<span>&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span>The transaction persists beyond the end of the code block, as multiple cmdlets can participate in it. Although the transaction persists outside of the code block, it is not <b>active \/ ambient<\/b> outside of the code block. A cmdlet or provider author can easily write the following code to tightly control which operations are transacted:<\/p>\n<pre><span><font><font face=\"Courier New\">using(CurrentPsTransaction)<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\">{<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\"><span>&nbsp;&nbsp; <\/span>... \/\/ Perform transactional work here<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\">}<\/font><\/font><\/span><\/pre>\n<pre><span><font face=\"Courier New\">&nbsp;<\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\">... \/\/ Perform non-transacted work here<\/font><\/font><\/span><\/pre>\n<pre><span><font face=\"Courier New\">&nbsp;<\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\">using(CurrentPsTransaction)<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\">{<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\"><span>&nbsp;&nbsp; <\/span>... \/\/ Perform more transactional work here<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\">}<\/font><\/font><\/span><\/pre>\n<pre><span><font face=\"Courier New\">&nbsp;<\/font><\/span><\/pre>\n<p class=\"MsoBodyText\">&nbsp;<\/p>\n<p class=\"MsoBodyText\">Using the same pattern PowerShell has established for the ShouldProcess functionality, cmdlet and provider authors should check for an existing transaction if they can operate without one:<\/p>\n<pre><span><font><font face=\"Courier New\">if(TransactionAvailable())<br \/>\n{<br \/>\n<span>&nbsp;&nbsp;&nbsp; <\/span>using(CurrentPsTransaction)<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\"><span>&nbsp;&nbsp;&nbsp; <\/span>{<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>... \/\/ Perform transactional work here<\/font><\/font><\/span><\/pre>\n<pre><span><font><font face=\"Courier New\"><span>&nbsp;&nbsp;&nbsp; <\/span>}<br \/>\n}<\/font><\/font><\/span><\/pre>\n<p class=\"MsoBodyText\">&nbsp;<\/p>\n<p class=\"MsoBodyText\">If the cmdlet or provider cannot operate without a transaction, they can simply use the CurrentPsTransaction property. If no transaction is available, PowerShell automatically generates an error.<\/p>\n<p class=\"MsoBodyText\">&nbsp;<\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">&#8212;<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Lee Holmes [MSFT]<\/font><\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><font face=\"Calibri\">Windows PowerShell Development<\/font><\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The second CTP of PowerShell V2 (CTP2) introduces full engine support for transactions \u2013 groups of actions that can be finalized or undone in an all-or-nothing way. Wikipedia gives a great overview of transactions here: http:\/\/en.wikipedia.org\/wiki\/Database_transactions. &nbsp; We put a ton of thought into how to expose this normally developer-centric concept in a way suitable [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[331],"class_list":["post-6221","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-transaction"],"acf":[],"blog_post_summary":"<p>The second CTP of PowerShell V2 (CTP2) introduces full engine support for transactions \u2013 groups of actions that can be finalized or undone in an all-or-nothing way. Wikipedia gives a great overview of transactions here: http:\/\/en.wikipedia.org\/wiki\/Database_transactions. &nbsp; We put a ton of thought into how to expose this normally developer-centric concept in a way suitable [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/6221","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=6221"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/6221\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=6221"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=6221"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=6221"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}