{"id":51203,"date":"2010-02-24T00:01:00","date_gmt":"2010-02-24T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/02\/24\/hey-scripting-guy-how-can-i-use-transactions-to-write-to-the-registry\/"},"modified":"2010-02-24T00:01:00","modified_gmt":"2010-02-24T00:01:00","slug":"hey-scripting-guy-how-can-i-use-transactions-to-write-to-the-registry","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-use-transactions-to-write-to-the-registry\/","title":{"rendered":"Hey, Scripting Guy! How Can I Use Transactions to Write to the Registry?"},"content":{"rendered":"<p class=\"MsoNormal\"><a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/p>\n<p class=\"MsoNormal\">Hey, Scripting Guy! I am interested in using transactions when writing to the registry, but if something does not work, I want the entire transaction to fail. It does not seem that this actually works in Windows PowerShell. Am I missing something?<\/p>\n<p class=\"MsoNormal\">&#8212; TW<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello TW, <\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. Today has been a great day, and I have spent much of the day in Live Meetings for the MVP program. It has been very informative. The cool thing has also been the &ldquo;back channel&rdquo; of tweets that have been flowing from the conference. I have found that all day meetings go great with Dragon Pearl Tea and an <a href=\"http:\/\/en.wikipedia.org\/wiki\/ANZAC_biscuit\"><font face=\"Segoe\">ANZAC biscuit<\/font><\/a>. <\/p>\n<p class=\"MsoNormal\">The MVP meetings are over, TW, so let us get to work on transactions. If you start a transaction by using the <b>Start-Transaction<\/b> cmdlet, perform an invalid WMI query, and then use the transaction to create a registry key, you might think that the transaction will fail. But the registry key will be created because there is no <b>&ndash;usetransaction<\/b> parameter on the <b>Get-WmiObject<\/b> cmdlet. The annoying message that is displayed when you use the <b>Start-Transaction<\/b> cmdlet states that only commands that use the <b>&ndash;usetransaction<\/b> parameter are included in the transaction. In the command sequence seen here, the registry key test is created under test2. <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Start-Transaction<\/p>\n<p>Suggestion [1,Transactions]: Once a transaction is started, only commands that get called with the -UseTransaction flag become part of that transaction.<\/p>\n<p>PS C:&gt; $a = gwmi win32_computerSystem -ComputerName localtoast<br \/>Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)<br \/>At line:1 char:10<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>+ $a = gwmi &lt;&lt;&lt;&lt;<span>&nbsp; <\/span>win32_computerSystem -ComputerName localtoast<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>+ CategoryInfo<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: InvalidOperation: (:) [Get-WmiObject], COMException<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand<\/p>\n<p>PS C:&gt; New-ItemProperty -Name memory -Value ($a.totalphysicalmemory).tostring() `<br \/>-Path HKCU:SoftwareScriptingGuystest2<br \/>You cannot call a method on a null-valued expression.<br \/>At line:1 char:71<br \/>+ New-ItemProperty -Name memory -Value ($a.totalphysicalmemory).tostring &lt;&lt;&lt;&lt; () -Path HKCU:SoftwareScriptingGuystest2<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>+ CategoryInfo<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: InvalidOperation: (tostring:String) [], RuntimeException<br \/><span>&nbsp;&nbsp;&nbsp; <\/span>+ FullyQualifiedErrorId : InvokeMethodOnNull<\/p>\n<p>PS C:&gt; New-ItemProperty -Name test -Value rolledback -Path HKCU:SoftwareScriptingGuystest2 -UseTransaction<\/p>\n<p>PSPath<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_USERSoftwareScriptingGuystest2<br \/>PSParentPath : Microsoft.PowerShell.CoreRegistry::HKEY_CURRENT_USERSoftwareScriptingGuys<br \/>PSChildName<span>&nbsp; <\/span>: test2<br \/>PSDrive<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: HKCU<br \/>PSProvider<span>&nbsp;&nbsp; <\/span>: Microsoft.PowerShell.CoreRegistry<br \/>test<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>: rolledback<\/p>\n<p>PS C:&gt; Complete-Transaction<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The new registry key is seen in the following image:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of the new registry key\" alt=\"Image of the new registry key\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/february\/hey0224\/hsg-02-24-10-01.jpg\" width=\"600\" height=\"420\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">To catch errors from cmdlets that do not directly participate in transactions, such as the <b>Get-WmiObject<\/b> cmdlet, you can use the <b>Try\/Catch\/Finally<\/b> sequence. This is illustrated in the TrapErrorInTransaction.ps1 script. This script requires Windows PowerShell 2.0 because of not only the use of the transaction cmdlets but also the use of the <b>Try\/Catch\/Finally<\/b> sequence. <\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>TrapErrorInTransaction.ps1<\/p>\n<p><\/strong><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">#requires &ndash;version 2.0<br \/>Function New-MemoryRegKey ($computer)<br \/>{<br \/><span>&nbsp;<\/span>$t = {Start-Transaction}<br \/><span>&nbsp;<\/span>&amp;($t)<br \/><span>&nbsp;<\/span>Try<br \/><span>&nbsp; <\/span>{<br \/><span>&nbsp;&nbsp; <\/span>$a = Get-WmiObject -Class win32_operatingSystem -ComputerName $computer -ErrorAction silentlyContinue<br \/><span>&nbsp;&nbsp; <\/span>Set-ItemProperty -Name FreeMemory -Path HKCU:SoftwareScriptingGuystest2 `<br \/><span>&nbsp;&nbsp; <\/span>-Value ($a.FreePhysicalMemory).ToString() -UseTransaction| out-null<br \/><span>&nbsp;&nbsp; <\/span>Complete-Transaction<br \/><span>&nbsp;&nbsp; <\/span>&#8220;registry Key updated&#8221;<br \/><span>&nbsp; <\/span>}<br \/><span>&nbsp;<\/span>Catch [System.Exception]<br \/><span>&nbsp; <\/span>{ <br \/><span>&nbsp;&nbsp;&nbsp; <\/span>Undo-Transaction <br \/><span>&nbsp;&nbsp;&nbsp; <\/span>&#8220;roll back transaction&#8221;<br \/><span>&nbsp; <\/span>}<br \/><span>&nbsp;<\/span>Finally { &#8220;done&#8221; }<br \/>} #end function New-MemoryReg\nKey<\/p>\n<p>new-MemoryRegKey localhost<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">My friend Luis, who is a Microsoft Premier Field Engineer in Lisbon, Portugal, showed me the trick to suppress the transaction message when calling the <b>Start-Transaction<\/b> cmdlet. To suppress the message, the first thing to do is place the <b>Start-Transaction<\/b> cmdlet in a script block and assign the results to the <b>$t<\/b> variable. Then we use the <b>invocation<\/b> operator to execute the <b>Start-Transaction<\/b> cmdlet. This provides us with a nice clean output. Here are the two lines of code:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$t = {Start-Transaction}<br \/><span>&nbsp;<\/span>&amp;($t)<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Next, we perform the WMI query, and attempt to create or update a registry key. When you want to attempt something, use the <b>Try<\/b> command. To suppress any errors from the WMI operation, set the <b>-erroraction<\/b> parameter to <b>SilentlyContinue<\/b>. If the WMI operation completes and the registry update completes without problem, commit the transaction. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Try<br \/><span>&nbsp; <\/span>{<br \/><span>&nbsp; <\/span><span>&nbsp;<\/span>$a = Get-WmiObject -Class win32_operatingSystem -ComputerName $computer -ErrorAction silentlyContinue<br \/><span>&nbsp;&nbsp; <\/span>Set-ItemProperty -Name FreeMemory -Path HKCU:SoftwareScriptingGuystest2 `<br \/><span>&nbsp;&nbsp; <\/span>-Value ($a.FreePhysicalMemory).ToString() -UseTransaction| out-null<br \/><span>&nbsp; <\/span><span>&nbsp;<\/span>Complete-Transaction<br \/><span>&nbsp;&nbsp; <\/span>&#8220;registry Key updated&#8221;<br \/><span>&nbsp; <\/span>} <\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">If an error occurs in the <b>Try<\/b> block, we want to roll back the transaction. A <b>system.exception<\/b> is the most generic error that could occur, and if it occurs, it will invoke the <b>Catch<\/b> block. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Catch [System.Exception]<br \/><span>&nbsp; <\/span>{ <br \/><span>&nbsp;&nbsp;&nbsp; <\/span>Undo-Transaction <br \/><span>&nbsp;&nbsp;&nbsp; <\/span>&#8220;roll back transaction&#8221;<br \/><span>&nbsp; <\/span>}<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The <b>Finally<\/b> block will always execute, whether an error occurs or not. In this example, we simply display a message that states that we are all done:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Finally { &#8220;done&#8221; }<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">If the <b>Try<\/b> block completes successfully, the registry key is updated if it previously existed. If it did not previously exist, it is created. This is seen in the following image.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of creating or updating a registry key\" alt=\"Image of creating or updating a registry key\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/february\/hey0224\/hsg-02-24-10-02.jpg\" width=\"600\" height=\"420\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">When the script runs and an error occurs, messages are displayed on the console. If it runs without errors, status updates are still displayed. These are simple strings, and could easily be modified or deleted as required. This is seen in the following image.<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of status updates being displayed\" alt=\"Image of status updates being displayed\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/february\/hey0224\/hsg-02-24-10-03.jpg\" width=\"600\" height=\"429\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">TW that is all there is to using transactions inside a <strong>Try\/Catch\/Finally<\/strong> block. Transaction Week will continue tomorrow. <\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\"><font face=\"Segoe\">Twitter<\/font><\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\"><font face=\"Segoe\">Facebook<\/font><\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\"><font face=\"Segoe\">Official Scripting Guys Forum<\/font><\/a>. See you tomorrow. Until then, peace.<\/p>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/p>\n<p><\/span><\/b><\/p>\n<p><b><span><\/span><\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Hey, Scripting Guy! I am interested in using transactions when writing to the registry, but if something does not work, I want the entire transaction to fail. It does not seem that this actually works in Windows PowerShell. Am I missing something? &#8212; TW &nbsp; Hello TW, Microsoft Scripting Guy Ed Wilson here. Today [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,3,4,45],"class_list":["post-51203","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Hey, Scripting Guy! I am interested in using transactions when writing to the registry, but if something does not work, I want the entire transaction to fail. It does not seem that this actually works in Windows PowerShell. Am I missing something? &#8212; TW &nbsp; Hello TW, Microsoft Scripting Guy Ed Wilson here. Today [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=51203"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/51203\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=51203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=51203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=51203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}