PowerShell - 本地运行类代码与远程运行类代码

问题描述 投票:0回答:1

我正在开发一个课程,该课程必须在本地和远程运行。简化版本在下面的代码中。

假设:

  • 我无法启动与远程服务器的 RDP 会话,但可以远程执行 PowerShell 代码。因此,请不要“转到服务器,并在那里运行代码”,这是一个简化版本,完整的代码必须在数十台服务器上运行。
  • 使用的模块(C:\Test\MyEmployee.psm1)保证通过自动系统存在于该文件夹中,无论是本地还是远程,每次保存后都会更新。
  • 远程计算机称为“远程”。但在我的脚本中,我确实使用了正确的服务器名称。

模块文件 C:\Test\MyEmployee.psm1 如下所示:

using namespace System.Collections.Generic

class MyEmployee
{
    [int]$UniqueID
    [string]$Firstname
    [string]$Lastname
    [string]$Folder

    MyEmployee( [int]$ID, [string]$First, [string]$Last, [string]$Folder )
    {
        $this.UniqueID  = $ID
        $this.Firstname = $First
        $this.Lastname  = $Last

        If( $Folder.Length -lt 0 )
        {
            $this.Folder    = $Folder
        }
        Else
        {
            $this.Folder    = "Employee" + $this.UniqueID.ToString( ).PadLeft( 5 , "0" )
        }
    }
}

class MyEmployees
{
    [List[MyEmployee]]$Employees

    MyEmployees( )
    {
        $this.Employees = [List[MyEmployee]]::New( )
    }
}

调用脚本如下所示:

using Module "C:\Test\MyEmployee.psm1"

Function RunCode( )
{
    $MyEmps          = [MyEmployees]::New( )
    $MyEmp           = [MyEmployee]::New( 1, "John", "Doe", "" )
    $MyEmps.Employees.Add( $MyEmp )

    ForEach( $MyEmp in $MyEmps.Employees )
    {
        Write-Host "Employee $( $MyEmp.UniqueID ) : $( $MyEmp.Lastname ), $( $MyEmp.Firstname ) "
    }
}

$ScriptBlock = {
    Import-Module "C:\Test\MyEmployee.psm1"

    $MyEmps          = [MyEmployees]::New( )
    $MyEmp           = [MyEmployee]::New( 1, "John", "Doe", "" )
    $MyEmps.Employees.Add( $MyEmp )

    ForEach( $MyEmp in $MyEmps.Employees )
    {
        Write-Host "Employee $( $MyEmp.UniqueID ) : $( $MyEmp.Lastname ), $( $MyEmp.Firstname ) "
    }
}


Clear-Host

$LocalHost  = $Env:ComputerName
$Servername = $LocalHost
#$Servername = "remote"

If( $Servername -eq $LocalHost )
{
    RunCode
}
Else
{
    $LogResult = $( Invoke-Command -ComputerName $ServerName -ScriptBlock $ScriptBlock )
}

当在本地运行时,无论是在“远程”还是在我的机器上,代码都可以完美执行,我得到了预期的结果:

Employee 1 : Doe, John
Employee 2 : Doe, Peter
Employee 3 : Doe, Jane
Employee 4 : Doe, Petra

但是,一旦我取消注释

#$Servername = "remote"
行,告诉 PowerShell 运行 ScriptBlock 而不是 te 函数,我就会收到以下错误:

Unable to find type [MyEmployees].
    + CategoryInfo          : InvalidOperation: (MyEmployees:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound
    + PSComputerName        : remote

我在这里做错了什么?是否可以在 PowerShell 中像这样远程运行类代码?

powershell class module remote-execution
1个回答
0
投票

Import-Module
不会公开
psm1
中定义的 PowerShell 类,您需要在
using module
中使用
$scriptblock
,就像在调用脚本中一样。如果您要创建一个只有类而没有函数的项目,那么使用
psm1
已经是不正确的方法,使用
ps1
会更容易,您可以 dot source (
. 'path\to\MyEmployeeClass.ps1'
)
.

如果您尝试将

using module
语句添加到
$scriptblock
中,下一个问题将是一个解析错误,因为“A 'using' 语句必须出现在脚本中的任何其他语句之前。PowerShell”,因此要解决此问题需要将您的代码定义为字符串,并使用
ScriptBlock.Create
.

从它创建一个脚本块

总结:

$ScriptBlock = [scriptblock]::Create(@'
    using module "C:\Test\MyEmployee.psm1"

    Import-Module "C:\Test\MyEmployee.psm1"

    $MyEmps          = [MyEmployees]::New( )
    $MyEmp           = [MyEmployee]::New( 1, "John", "Doe", "" )
    $MyEmps.Employees.Add( $MyEmp )

    ForEach( $MyEmp in $MyEmps.Employees )
    {
        Write-Host "Employee $( $MyEmp.UniqueID ) : $( $MyEmp.Lastname ), $( $MyEmp.Firstname ) "
    }
'@)

那么假设

Invoke-Command
存在于
C:\Test\MyEmployee.psm1
中,
$ServerName
语句应该可以正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.