Windows PowerShell: Getting Transactional
PowerShell can now support transactional operations, but there is a hierarchy to how it works.
There’s power in numbers. One of the new features in Windows PowerShell v2 is support for transactional operations. Generally speaking, a transaction is two or more discrete operations that must either succeed or fail together as a group.
Suppose you’re writing a batch of commands that modify several registry keys. One modification could fail due to a lack of permissions or some other glitch. If that happens, you don’t want to save any of those changes. You only want the batch of changes to occur if they’re all completed successfully. That’s exactly what the shell’s transactions can provide.
What You’ll Need
Besides Windows PowerShell v2, transactions are only available on Windows Vista, Windows Server 2008, and later versions of Windows. Although Windows PowerShell v2 will run on the older Windows XP and Windows Server 2003 operating systems, the shell’s transactional support does not extend to those versions.
That will become a common pattern as Windows PowerShell evolves: Newer versions of the shell may run on older versions of the OS, but specific features may only be available when you’re running the shell on a newer version of Windows.
The shell supports transactions through its PSDrive providers. A PSDrive adapts some form of storage—like the registry or the file system—to look like a standard disk file system. The PSDrive provider must specifically support transactions. In v2 of the shell, only the registry provider supports transactions out of the box.
The shell also permits other cmdlets to support transactions and those transactions will include a –UseTransaction parameter. Essentially, the shell provides the framework for a transaction. Then the specific cmdlets or PSDrive providers must actually implement the capabilities necessary to use those transactions.
Starting a Transaction
You can begin a transaction by simply running Start-Transaction. If you don’t include any parameters, and there’s no transaction already started, then it will start a new one. If you run the cmdlet while a transaction is already in progress, then you’re simply joining the existing transaction and not starting a new one.
If you run Start-Transaction –independent, then a new, independent transaction is started and made active. You can start multiple transactions at once, but only one can be active at a time. This can result in a hierarchy of transactions:
- Transaction 1 (Start-Transaction)
- Transaction 2 (Start-Transaction –independent)
- Transaction 3 (Start-Transaction –independent)
If Transaction 3 is active, then every supported command run within it becomes a part of that transaction. When you end Transaction 3, either by rolling it back or committing it, Transaction 2 will once again be active. Although only one transaction can be active at a time, they are not tested. That is, suppose you complete Transaction 3, but abort Transaction 2. Anything completed as part of Transaction 3 will remain.
You can always run Get-Transaction to see what transactions are currently active. By default, a transaction will automatically roll back (more on that in a moment) when an error occurs on a cmdlet within the transaction; you can specify alternate rollback preferences using parameters of Start-Transaction.
Using a Transaction
Once you start a transaction, you must explicitly attach commands to it using the –UseTransaction parameter. Even if a cmdlet supports transactions, it will not use them automatically. You must specify the parameter in order for the operation to be covered by the transaction, like so:
Cd hkcu:\software Mkdir test Start-transaction Del test –usetransaction Dir
The directory listing will include the test registry key. Although that key was deleted, the deletion was part of a transaction that has not yet been committed. If you run Dir –usetransaction, you will see the directory listing as it exists within the transaction. The test key will not be listed.
Closing a Transaction and Transaction Tips
You can close a transaction in one of two ways:
- Undo-Transaction will roll back any commands that were part of the transaction
- Complete-Transaction will make permanent any commands that were part of the transaction
The Use-Transaction cmdlet lets you run any command as part of a transaction. However, you can only include commands that utilize transaction-enabled Microsoft .NET Framework objects. You can’t just pop any old command in there and have it work. For more information, run Help about_transactions.
Currently, the ability to do transactions within the registry might seem to be marginally useful. Underlying support for transactional file system operations already exists, although the file system PSDrive provider doesn’t yet support them. Microsoft seems to be leaning toward making more .NET Framework objects—which is what Windows PowerShell is built on—transactional. In the future, maybe you can even transact Active Directory operations.
The good news is that the shell already supports disparate transactions. In other words, if the file system did support transactions (and it’s doubtless that it will one day), a single transaction could mix both file and registry operations—making quite a useful tool indeed.
- Windows PowerShell: Writing Cmdlets in Script
- Windows PowerShell 2.0 Brings Scripting to Active Directory — and Not Just for Windows Server 2008 R2
- Windows PowerShell: What Not to Script