PowerShell - 将对象传递给启动作业 - 反序列化

2024-01-11

我知道通过 start-job 执行的脚本块无法看到脚本块之外的变量。要传递变量,请使用-arguments范围。从我读过的 doco 来看,作业不能在没有连载 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_jobs?view=powershell-7.1他们。显然这是因为工作的工作方式 - 使用时Start-job,PowerShell 创建一个新进程并在那里运行命令;为了将对象传输到另一个进程,它需要将其序列化,然后另一个 exe 在导入时将其反序列化。当您想在启动作业中使用对象时,这会带来问题。

NOTE:下面是演示我的问题的示例 - 我运行的实际 cmdlet 和脚本完全不同且更复杂,因此,如果您想知道为什么我会以这种方式运行这些命令,请记住我不会,他们只是简单的命令来演示我的问题。

以下是我用于简单 Get-aduser 命令的语法示例

$user = get-aduser samaccount

当我们输出 $user 时,我们看到该对象的类型ADUser

$user|GM
TypeName: Microsoft.ActiveDirectory.Management.ADUser

现在让我们序列化该对象(以模拟 start-job 的作用)

$user| Export-Clixml C:\temp\test.xml

现在重建它(反序列化)

$user = Import-Clixml C:\temp\test.xml

现在,当我们查看它的类型时,它是不同的。它前面有“反序列化”一词。

 $user|GM
TypeName: Deserialized.Microsoft.ActiveDirectory.Management.ADUser

我现在遇到的问题是它不是原始对象的真实表示。即使所有属性和设置都相同,我们仍然存在对象类型不同的问题。现在来演示为什么这是一个问题。

Get-aduser接受一个字符串作为输入(第一个示例),但它也将接受一个有效的ADuser目的。但是当我们现在运行时:

get-aduser $user

我们得到以下错误:

"Cannot convert the "AD_distinguishedname_here. I have omitted this for security reasons" value of type 
"Deserialized.Microsoft.ActiveDirectory.Management.ADUser" to type "Microsoft.ActiveDirectory.Management.ADUser"."

此错误是因为 Get-aduser 希望您提供类型的对象Microsoft.ActiveDirectory.Management.ADUser但我们提供了Deserialized.Microsoft.ActiveDirectory.Management.ADUser并且它不知道如何转换它。这正是您通过 start-job 运行命令时发生的情况以及无法将对象传递给作业的原因。

正如我上面所说,我没有在实际代码中使用 get-aduser,我只是使用每个人都可以访问的这个简单命令来演示该问题。在我的真实代码中我must为工作提供一个对象。

所以我的问题是,有谁知道如何解决这个问题或知道如何以原始形式重建对象?


在这条直线上花了 8 个小时后,我终于弄清楚发生了什么。这是一个很长的故事,但总而言之,您无法使用任何本机工具来解决这个问题 - 您必须在启动作业脚本块内重建对象,如果您有一个大型复杂对象,这是不可行的。我最终找到了一个可以下载的模块,它通过启动线程而不是启动作业运行命令,并且不使用序列化。指南在这里 https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_thread_jobs?view=powershell-7.1到DL并安装它。当我测试它时这有效

要获取 PowerShell 模块,请转到 PowerShell 库并搜索“start-thread”

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PowerShell - 将对象传递给启动作业 - 反序列化 的相关文章

随机推荐