在新的,干净的PowerShell实例(来自另一个脚本中)中调用PowerShell脚本



我有很多脚本。进行更改后,我喜欢运行它们,看看我是否打破了任何东西。我写了一个脚本以遍历每个脚本,在新的数据上运行它。

在我的循环中,我目前正在运行powershell.exe -command <path to script>。我不知道这是这样做的最好方法,还是两个实例彼此完全分开。

在PowerShell的干净实例中运行脚本的首选方法是什么?还是我应该说"会议"?

使用powershell.exe似乎是一种很好的方法

专利:

  • 在单独的干净会话中调用每个脚本。
  • 甚至崩溃都不会停止整个测试过程。

cons:

  • 调用powershell.exe有些慢。
  • 测试取决于退出代码,但0并不总是意味着成功。

没有提到任何问题是一个潜在问题。

下面的演示脚本。它已通过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."
    }
}

如果您在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社区扩展。它具有Test-Script命令,该命令可以检测脚本文件中的语法错误。当然,它不会捕获运行时错误。

PowerShell V3用户的一个提示:我们(PowerShell团队)在Runspace类上添加了一个新的API,称为ResetrunSpace()。该API将全局变量表重置回该Runspace的初始状态(以及清理其他一些内容)。它不做的是清理功能定义,类型和格式文件或卸载模块。这允许API更快。还要注意,必须使用缩写式对象而不是RunspaceConfiguration实例来创建Runspace。作为V3中工作流功能的一部分,添加了ResetrunSpace(),以在脚本中有效地支持并行执行。

这两个实例是完全分开的,因为它们是两个不同的过程。通常,这并不是每个脚本运行的powershell过程的最有效方法。根据脚本的数量以及重新运行的频率,它可能会影响您的整体性能。如果不是这样,我会留下一切。

另一个选项是在同一runspace中运行(这是一个正确的单词),但每次都清理所有内容。请参阅此答案,以便做到这一点。或在下面使用:

$sysvars = get-variable | select -Expand name
function remove-uservars {
 get-variable |
   where {$sysvars -notcontains $_.name} |
     remove-variable
}

最新更新