在生产中分析 powershell cmdlet 的最佳方法是什么?假设您编写了一个执行以下操作的脚本 -
- 写入注册表值的 lof
- 注册 COM Dll
- 制作 IIS 应用程序池
- 启动 Windows 服务
&...中间出了点问题,那么通知用户以便可以跟踪和调试根问题的最佳实践是什么?
假设,由于某种原因,用户凭证创建 AppPool 失败,我想在那个时候停止处理,而且我想回滚我之前所做的事情。
详细模式 + 记录是在每一步收集每个细节的优雅方式吗?
在生产中分析 powershell cmdlet 的最佳方法是什么?假设您编写了一个执行以下操作的脚本 -
- 写入注册表值的 lof
- 注册 COM Dll
- 制作 IIS 应用程序池
- 启动 Windows 服务
&...中间出了点问题,那么通知用户以便可以跟踪和调试根问题的最佳实践是什么?
假设,由于某种原因,用户凭证创建 AppPool 失败,我想在那个时候停止处理,而且我想回滚我之前所做的事情。
详细模式 + 记录是在每一步收集每个细节的优雅方式吗?
我编写了一个Write-Log
在 poshcode ( http://poshcode.org/3270 ) 上发布的函数,用于生产级 PowerShell 程序。或者,您可以使用Start-Transcript
which 将控制台上显示的几乎所有内容记录到文件中。有几个关于Start-Transcript
-
Out-Host
诸如ping.exe localhost | Out-Host
.$host
.我通常用于错误处理的模式是将所有内容包装在 try/catch 中。异常对象将$_
在 catch 块中可用。它将包含有关发生的错误的所有信息、消息、行号和列号等...
我还将 设置$ErrorActionPreference
为Stop
以便所有 cmdlet 都会引发终止错误,因此脚本不会继续。它看起来像这样:
$ErrorActionPreference = "Stop"
try {
# Write lof of registry values
New-Item -Path HKCU:\Software\MyTest -ItemType Directory
New-ItemProperty -Path HKCU:\Software\MyTest -Name MyTestValue -Value Test
# Register COM Dlls
regsrv32 my.dll
if ($LASTEXITCODE -ne 0) { throw "Failed to register my.dll" }
# Make IIS AppPools
IIS:\>New-WebAppPool NewAppPool
# Start Windows Services
Start-Service -Name MyService
} catch {
Write-Log ("Script failed. The error was: '{0}'." -f $_)
}
回滚并不容易......唯一可能容易回滚的是注册表操作,因为注册表支持事务(假设 Vista 或更高版本)。您可以只创建一个事务(如数据库)并在发生错误时将其回滚。您提到的其余操作将需要特定的代码来回滚它们。您可以像这样将回滚代码添加到 catch 块中:
} catch {
# Undo the registry transaction.
# Unregister the DLL.
# Delete the App pool if it exists.
# Stop the windows service.
}
对于直接注册表操作,您可以使用 PowerShell 的事务支持在脚本整体成功时提交更改或撤消事务以回滚注册表更改,例如:
try {
$ErrorActionPreference = 'Stop' # convert all errors to terminating errors
Start-Transaction
Set-ItemProperty Acme -Name Count -Value 99 -UseTransaction
Remove-ItemProperty Acme -Name InstallDir -UseTransaction
New-Item Acme2 -UseTransaction
New-ItemProperty Acme2 -Name Count -Value 2 -UseTransaction
New-ItemProperty Acme2 -Name InstallDir -Value 'C:\Program Files\Acme2' -UseTx
... do other stuff ...
Complete-Transaction
}
catch {
Undo-Transaction
... Log failure ...
}