我有很多脚本。在进行更改后,我喜欢运行它们以查看是否有任何损坏。我编写了一个脚本来遍历每个脚本,并在新数据上运行它。
在我的循环中,我正在运行powershell.exe -command <path to script>
。我不知道这是否是最好的方法,或者两个实例是否彼此完全分开。
在干净的PowerShell实例中运行脚本的首选方法是什么?或者我应该说“会话”?
答案 0 :(得分:8)
使用powershell.exe
似乎是一种很好的方法,但当然也有其优点和缺点。
优点:
缺点:
powershell.exe
有点慢。没有提到的缺点是一个潜在问题的问题。
演示脚本如下。它已经过PS v2和v3测试。脚本名称
可能包括特殊字符,如空格,撇号,括号,反引号,
美元。注释要求中提到的一个是获取脚本路径的能力
在他们的代码中。通过提出的方法,脚本可以获得自己的路径
$MyInvocation.MyCommand.Path
# make a script list, use the full paths or explicit relative paths
$scripts = @(
'.\test1.ps1' # good name
'.\test 2.ps1' # with a space
".\test '3'.ps1" # with apostrophes
".\test [4].ps1" # with brackets
'.\test `5`.ps1' # with backticks
'.\test $6.ps1' # with a dollar
'.\test ''3'' [4] `5` $6.ps1' # all specials
)
# process each script in the list
foreach($script in $scripts) {
# make a command; mind &, ' around the path, and escaping '
$command = "& '" + $script.Replace("'", "''") + "'"
# invoke the command, i.e. the script in a separate process
powershell.exe -command $command
# check for the exit code (assuming 0 is for success)
if ($LastExitCode) {
# in this demo just write a warning
Write-Warning "Script $script failed."
}
else {
Write-Host "Script $script succeeded."
}
}
答案 1 :(得分:6)
如果您使用的是PowerShell 2.0或更高版本,则可以使用作业执行此操作。每个作业都在单独的PowerShell进程中运行,例如:
$scripts = ".\script1.ps1", ".\script2.ps1"
$jobs = @()
foreach ($script in $scripts)
{
$jobs += Start-Job -FilePath $script
}
Wait-Job $jobs
foreach ($job in $jobs)
{
"*" * 60
"Status of '$($job.Command)' is $($job.State)"
"Script output:"
Receive-Job $job
}
另外,请查看PowerShell Community Extensions。它有一个Test-Script
命令,可以检测脚本文件中的语法错误。当然,它不会捕获运行时错误。
答案 2 :(得分:3)
PowerShell V3用户的一个提示:我们(PowerShell团队)在Runspace类上添加了一个名为ResetRunspace()的新API。此API将全局变量表重置为该运行空间的初始状态(以及清理其他一些内容)。它不做的是清理函数定义,类型和格式文件或卸载模块。这允许API更快。另请注意,必须使用InitialSessionState对象而不是RunspaceConfiguration实例创建Runspace。 ResetRunspace()作为V3中工作流功能的一部分添加,以支持脚本中的并行执行。
答案 3 :(得分:2)
这两个实例是完全分开的,因为它们是两个不同的过程。通常,它不是每个脚本运行启动Powershell进程的最有效方法。根据脚本的数量以及重新运行它们的频率,它可能会影响您的整体性能。如果不是,我会按原样保留原样。
另一种选择是在同一个runspace中运行(这是一个正确的词),但每次都清理一切。请参阅this answer了解相关方法。或者使用以下摘录:
$sysvars = get-variable | select -Expand name
function remove-uservars {
get-variable |
where {$sysvars -notcontains $_.name} |
remove-variable
}