运行 来自 Python 的 powershell 脚本,无需在每个 运行 上重新导入模块

Running powershell scripts from Python without reimporting modules on every run

我正在创建一个 Python 脚本来调用需要导入 Active-Directory 模块的 Powershell 脚本 script.ps1。但是,每次我 运行 powershell 脚本使用 check_output('powershell.exe -File script.ps1') 它需要为每个 运行 脚本重新导入活动目录模块。ps1,这使得 运行 时间比它需要的时间长大约 3 秒。

那时我在想,是否有办法保持 Powershell 模块的导入(就好像它是直接从 Powershell 运行 而不是从 Python 导入的)以便我可以使用像

这样的东西
if(-not(Get-Module -name ActiveDirectory)){
  Import-Module ActiveDirectory
}

加快执行时间。

此解决方案使用 PowerShell 远程处理,并要求您远程进入的计算机具有 ActiveDirectory 模块,并且要求进行远程连接的计算机(客户端)是 PowerShell 版本 3 或更高版本。

在此示例中,机器远程进入自身。

这将是您的脚本。ps1 文件:

#requires -Version 3.0

$ExistingSession = Get-PSSession -ComputerName . | Select-Object -First 1

if ($ExistingSession) {
    Write-Verbose "Using existing session" -Verbose
    $ExistingSession | Connect-PSSession | Out-Null
} else {
    Write-Verbose "Creating new session." -Verbose
    $ExistingSession = New-PSSession -ComputerName . -ErrorAction Stop
    Invoke-Command -Session $ExistingSession -ScriptBlock { Import-Module ActiveDirectory }
}

Invoke-Command -Session $ExistingSession -ScriptBlock {
    # do all your stuff here
}

$ExistingSession | Disconnect-PSSession | Out-Null

它利用了 PowerShell 对断开连接的会话的支持。每次你 shell 到 PowerShell.exe,你最终会连接到一个已经加载 ActiveDirectory 模块的现有会话。

完成所有调用后,您应该销毁会话:

Get-PSSession -ComputerName . | Remove-PSSession

这是在每个 运行 上通过单独的 powershell.exe 调用进行测试的。

我确实想知道您延迟的原因是否实际上是因为加载 ActiveDirectory 模块,或者是否至少有很大一部分延迟仅仅是由于必须加载 PowerShell.exe 本身造成的。