0

我有以下名为 module.psm1 的 PowerShell 模块。这是一个简化的例子。我正在针对 SharePoint 2013 执行操作,因此我需要模块中的 SharePoint 管理单元

function Test() {
    if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
        Write-Verbose "Adding" -Verbose
        Add-PSSnapin "Microsoft.SharePoint.PowerShell" -Verbose
    }
    else {
        Write-Verbose "Already loaed" -Verbose
    }

    if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -ne $null) {
        Write-Verbose "Removing" -Verbose
        #Remove-PSSnapin "Microsoft.SharePoint.PowerShell" -Verbose
    }
    else {
        Write-Verbose "Already removed" -Verbose
    }

    Get-PSSnapin "Microsoft.SharePoint.PowerShell"

    if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell") -eq $null) {
        Write-Verbose "Adding" -Verbose
        Add-PSSnapin "Microsoft.SharePoint.PowerShell" -Verbose
    }
    else { 
        Write-Verbose "Already loaded" -verbose
    }
}

Export-ModuleMember -Function 'Test'

在我的 moduletest.ps1 中,我调用了 Test 和相同的逻辑

Import-Module "$PSScriptRoot\module.psm1" -Force

Test

if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -eq $null) {
    Write-Verbose "Adding" -Verbose
    Add-PSSnapin "Microsoft.SharePoint.PowerShell" -Verbose
}
else {
    Write-Verbose "Already loaed" -Verbose
}

if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue) -ne $null) {
    Write-Verbose "Removing" -Verbose
    Remove-PSSnapin "Microsoft.SharePoint.PowerShell" -Verbose
}
else {
    Write-Verbose "Already removed" -Verbose
}

Get-PSSnapin "Microsoft.SharePoint.PowerShell"

if ((Get-PSSnapin "Microsoft.SharePoint.PowerShell") -eq $null) {
    Write-Verbose "Adding" -Verbose
    Add-PSSnapin "Microsoft.SharePoint.PowerShell" -Verbose
}
else { 
    Write-Verbose "Already loaded" -verbose
}

当我从模块运行功能测试时,输出是:

VERBOSE: Adding
VERBOSE: Removing
VERBOSE: Performing the operation "Remove-PSSnapin" on target "Microsoft.SharePoint.PowerShell".
VERBOSE: Already loaded

所以在模块中,当我以某种方式移除 SNapIn 时,它并没有真正消失。当我直接从 ps1 文件运行代码时,我得到:

VERBOSE: Adding
VERBOSE: Removing
VERBOSE: Performing the operation "Remove-PSSnapin" on target "Microsoft.SharePoint.PowerShell".
VERBOSE: Adding

在我的 ps1 文件中,Remove 实际上完全删除了 SnapIn。这是正常行为吗?我看到其他 SnapIn 的行为相同。

我的另一个问题是:

当我从控制台导入模块并从模块加载管理单元并从控制台中的管理单元执行命令时,不会识别任何 cmdlet。当我在模块中加载管理单元时,是在不同的范围或上下文中完成的吗?

4

1 回答 1

0

I think how you ran this was you did a call to .\moduletest.ps1, and you are describing the output you received from running the Test function within module.psm1 and then the output you received from the lines of code within moduletest.ps1 itself afterwards. This would've been more helpful in the description of your question, in order to reproduce the issue. I wasn't sure, at first, if you were saying you were running the lines from the files individually in the ISA or running lines in the command window or both, and which ones where.

If you remove a snapin in the context of a script, you obviously need to add it back in the same script if you want to use it again within that script or a session - it does get removed. If you perform some commands at the command line, these would be done in the same context/session as a script called before it is ran in. Ex. if you had the line $myVariable = "Sushi" inside a file called mycode.ps1 and you did .\mycode.ps1 at the command line, and then you did Write-Host $myVariable at the command line right after, it would print Sushi.

When you are running your ps1 script lines, this has the ability to remove a snapin, and apparently it does it quickly. When you are trying to remove a snapin from within a function in a module (as you are in module.psm1), it apparently is still happening, but happening much too slow to be re-added (the re-add fails because it thinks it is still there), because you say when you launch snapin-based commands after the removal/reloading, these fail. I think the module is indeed removing the snapin, but just not reporting to your script it is removed when it checks, in order to be able to re-add it. If you add a delay during the module's Test function between the removal and when it tries to do the re-add of probably 100-200 ms, it will probably succeed at re-adding it just fine:

Start-Sleep -m 200

You generally don't ever even really need to remove the snapin, though - it will remove on its own when the session (window) is closed/script is ended. If you load a snapin that is already loaded, it doesn't matter, either - you should be able to keep loading commands.

于 2019-03-12T21:37:00.910 回答