简体   繁体   English

从Python运行powershell脚本,无需在每次运行时重新导入模块

[英]Running powershell scripts from Python without reimporting modules on every run

I am creating a Python script that calls a Powershell script script.ps1 that needs to import the Active-Directory module. 我正在创建一个Python脚本,调用需要导入Active-Directory模块的Powershell脚本script.ps1 However, every time I run the powershell script using check_output('powershell.exe -File script.ps1') it needs to re-import the active directory module for each run of script.ps1, which makes the run time take about 3 seconds longer then it needs to. 但是,每次使用check_output('powershell.exe -File script.ps1')运行powershell脚本时,都需要为每次运行script.ps1重新导入活动目录模块,这使得运行时间大约需要3秒它需要更长的时间。

I was wondering then, if there was a way to keep the Powershell module imported (as if it were being ran directly from Powershell, and not from Python) so that I can use things like 我当时想知道,如果有办法保持导入Powershell模块(好像是直接从Powershell运行,而不是从Python运行),这样我就可以使用像

if(-not(Get-Module -name ActiveDirectory)){
  Import-Module ActiveDirectory
}

to speed up execution time. 加快执行时间。

This solution uses PowerShell remoting, and requires that the machine you remote into has the ActiveDirectory module, and it requires that the machine making the remote connection (the client) be PowerShell version 3 or higher. 此解决方案使用PowerShell远程处理,并要求您远程访问的计算机具有ActiveDirectory模块,并且要求进行远程连接的计算机(客户端)为PowerShell版本3或更高版本。

In this example, the machine remotes into itself. 在这个例子中,机器进入自身。

This would be your script.ps1 file: 这将是你的script.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

It takes advantage of PowerShell's support for disconnected sessions. 它利用PowerShell对断开连接的会话的支持。 Each time you shell out to PowerShell.exe, you end up connecting to an existing session with the ActiveDirectory module already loaded. 每次弹出PowerShell.exe时,最终都会连接到已加载ActiveDirectory模块的现有会话。

Once you're done with all the calls, you should destroy the session: 完成所有调用后,您应该销毁会话:

Get-PSSession -ComputerName . | Remove-PSSession

This was tested with a separate powershell.exe invocation on every run. 这是在每次运行时使用单独的powershell.exe调用进行测试的。

I do wonder if the cause for your delays is actually because of loading the ActiveDirectory module though, or if at least a significant portion of the delays are caused merely by having to load PowerShell.exe itself. 我确实想知道延迟的原因是否真的是因为加载了ActiveDirectory模块,或者至少很大一部分延迟是由于必须加载PowerShell.exe本身造成的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM