You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PowerShell作业中调用类对象?遇类型未找到错误

问题描述

我创建了Test PowerShell类,计划通过后台并行作业创建该类对象并执行类中的方法。编写相关代码后,作业显示完成但未达预期,查看作业详情发现每个作业均报错:无法找到[Test]类型,以及无法找到ComputerName属性。

原代码

class Test {

    [String]$ComputerName
    
    
    [String]TestMrParameter() {

        if ($this.ComputerName -eq 'jhon'){throw "Bad thing happened"}
        
        return $this.ComputerName 

    }
}

$names = @('david', 'jhon', 'mark','tent')
$jobs = [System.Collections.ArrayList]@()

function TestMrParameter2 {
    param (
        [String]$name
    )
    [Test]$obj = [Test]::new()
    $obj.ComputerName = $name
    Write-Host $name + "TestMrParameter2 Function Reached!!!"
    $output=$obj.TestMrParameter()
    Write-Host "Output of the Test class is" + $output
}


foreach ($name in $names) {

    $out = Start-Job -ScriptBlock ${Function:TestMrParameter2} -ArgumentList $name
    $jobs.Add($out) | out-null

}

错误信息

Unable to find type [Test].
    + CategoryInfo          : InvalidOperation: (Test:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound
    + PSComputerName        : localhost
 
The property 'ComputerName' cannot be found on this object. Verify that the property exists and can 
be set.
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound
    + PSComputerName        : localhost

原因分析

PowerShell后台作业(Start-Job)会启动独立的子运行会话,当前会话中定义的类不会自动同步到子会话。你仅传递了函数TestMrParameter2,但函数依赖的Test类在子会话中未定义,因此会触发类型找不到的错误;后续的属性找不到错误是因为类不存在,对象创建失败导致的。

解决方案

方法1:通过初始化脚本在作业中加载类

将Test类的定义放到作业的初始化脚本中,确保作业启动时先加载类:

$names = @('david', 'jhon', 'mark','tent')
$jobs = [System.Collections.ArrayList]@()

# 初始化脚本:作业启动时加载Test类
$initScript = {
    class Test {
        [String]$ComputerName
        
        [String]TestMrParameter() {
            if ($this.ComputerName -eq 'jhon'){throw "Bad thing happened"}
            return $this.ComputerName 
        }
    }
}

function TestMrParameter2 {
    param (
        [String]$name
    )
    [Test]$obj = [Test]::new()
    $obj.ComputerName = $name
    # 修正字符串拼接方式,避免输出多余的+符号
    Write-Host "$name TestMrParameter2 Function Reached!!!"
    try {
        $output = $obj.TestMrParameter()
        Write-Host "Output of the Test class is $output"
        # 返回结果方便后续获取
        return $output
    }
    catch {
        Write-Error $_
        return $_
    }
}

foreach ($name in $names) {
    $out = Start-Job -InitializationScript $initScript -ScriptBlock ${Function:TestMrParameter2} -ArgumentList $name
    $jobs.Add($out) | Out-Null
}

# 等待所有作业完成并接收结果
$jobs | Wait-Job | Receive-Job

方法2:将类定义保存为脚本文件导入

如果类定义较复杂,可将其保存为单独的脚本文件(如TestClass.ps1),再在作业初始化时导入:

TestClass.ps1内容:

class Test {
    [String]$ComputerName
    
    [String]TestMrParameter() {
        if ($this.ComputerName -eq 'jhon'){throw "Bad thing happened"}
        return $this.ComputerName 
    }
}

主脚本修改为:

$names = @('david', 'jhon', 'mark','tent')
$jobs = [System.Collections.ArrayList]@()

function TestMrParameter2 {
    param (
        [String]$name
    )
    [Test]$obj = [Test]::new()
    $obj.ComputerName = $name
    Write-Host "$name TestMrParameter2 Function Reached!!!"
    try {
        $output = $obj.TestMrParameter()
        Write-Host "Output of the Test class is $output"
        return $output
    }
    catch {
        Write-Error $_
        return $_
    }
}

foreach ($name in $names) {
    # 替换为实际的TestClass.ps1文件路径
    $out = Start-Job -InitializationScript { . "C:\scripts\TestClass.ps1" } -ScriptBlock ${Function:TestMrParameter2} -ArgumentList $name
    $jobs.Add($out) | Out-Null
}

$jobs | Wait-Job | Receive-Job

额外说明:原代码中Write-Host用+拼接字符串会导致输出格式错误,已修正为双引号插值的方式,避免输出多余的+符号。

内容的提问来源于stack exchange,提问作者Chethiya Amarasinghe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 05:53:33