PowerShell - 将对象传递给开始作业 - 反序列化

PowerShell - Passing OBJECTS to start-job - deserialize

我知道通过 start-job 执行的脚本块无法看到脚本块之外的变量。要传递变量,请使用 -arguments 参数。不过,从我读过的 doco 来看,没有 serialising 作业就无法将对象相互传递。显然这是因为作业的工作方式——当使用 Start-job 时,PowerShell 会创建一个新进程并在其中 运行 发送命令;为了将对象传输到它需要序列化的其他进程,然后另一个 exe 将在导入时反序列化它。当您想要将对象与 start-job 一起使用时,这会带来问题。

注意:以下是演示我的问题的示例 - 我 运行ning 的实际 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

现在当我们查看它的类型时,它是不同的。前面有'derserialzed'字样。

 $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,我只是使用这个每个人都可以访问的简单命令来演示这个问题。在我的真实代码中,我 必须 为作业提供一个对象。

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

在这条直线上花了 8 个小时后,我终于弄明白是怎么回事了。这是一个很长的故事,但是 TLDR 版本是您无法使用任何本机工具来解决这个问题 - 您必须在 start-job 脚本块内重建对象,如果您有一个大的复杂对象,这是不可行的。我最终找到了一个你可以下载的模块,它通过启动线程而不是启动作业运行命令,而且它不使用序列化。 Guide here 到 DL 并安装它。这在我测试时有效

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