从一个 PSSession 获取输入并将其发送到另一个

Taking input from one PSSession and sending it to another

与许多其他人一样,我的背景是 Linux,没有任何 Powershell 经验。所以这个面向对象的编程把我搞砸了。

我需要通过 VMware Horizo​​n 搜索分配有用户的 VM,然后检查它们是否在 AD 中被禁用。如果它们在 AD 中被禁用,我想回收 VM。

目前我正在从 VMware Horizo​​n 中提取用户的 SID,但是当我尝试在针对 AD 的调用命令中使用这些时,我收到以下错误

"Object reference not set to an instance of an object"

到目前为止的脚本

function getlist() {
$temp=Invoke-Command -ComputerName $vdiserver -ScriptBlock { add-pssnapin vmware.view.broker; get-desktopvm | select user_sid }
$list=$temp | Select-Object user_sid
#$list
}
$vdi1="server1"
$vdi2="server2"
$test=Test-Connection -ComputerName $vdi1 -Quiet
$test2=Test-Connection -ComputerName $vdi2 -Quiet
if ($test -eq "True"){
$vdiserver=$vdi1
getlist
}
elseif ($test2 -eq "True"){
$vdiserver=$vdi2
getlist
}
else {echo "No servers to connect to"}

ForEach ($user in $list) #{
#echo $user
#sleep 1
#}
{Invoke-Command -ComputerName domaincontroller -ScriptBlock {param($p1) get-aduser -identity $p1 } -argumentlist $user}

So this object oriented programming is messing me up.

所以您正在尝试恢复到 shell 脚本,并编写两倍的代码来实现一半的工作量。

您遗漏的最重要一点是将一个对象想象成事物的集合 - 例如,想象您正在使用 /etc/passwd 并且每一行都有一个用户 ID 并且 一个组 ID 一个主目录 一个登录名 shell.. 你正在传递整行一下子转过来,那是你的类比对象。

一个对象有很多属性,就是这样(但总体上更有能力)。

当您 Select user_sid 选择该字段保留在 'line' 中时,该行仍然类似于 :::user_sid::::,其他字段现在为空。 (大约)。但他们仍然在那里,挡在路上。要直接使用它,您必须将它完全从 'line' 中取出 - 将容器扔掉,然后将 user_sid 放在它外面。

get-desktopvm | select user_sid

->

get-desktopvm | select -expandproperty user_sid

这使得 "sid1", "sid2", "sid3",但每个 sid 都没有容器。


这个

function getlist() {
    $temp=Invoke-Command -ComputerName $vdiserver -ScriptBlock { add-pssnapin vmware.view.broker; get-desktopvm | select user_sid }
    $list=$temp | Select-Object user_sid
}

本质上是在说

function getlist() {
    #do any amount of work here, and throw it all away.
}

因为函数returns什么都没有,它不会改变磁盘上的任何数据或任何东西,所以当函数完成时,变量被清除出内存,之后你不能使用它们.


这个:

if ($test -eq "True"){

有点废话。它可能会工作,但它没有按照您的预期工作,因为 "a string with content" 与布尔值 True 相比是 True 的偶然事件,无论字符串是否包含英文单词 "True" 。但它也是多余的 - $test 本身就是真或假,你不需要将 True 与任何东西进行比较。 if ($test)。甚至 if (Test-Connection -ComputerName $vdi -Quiet)


但是,还有很多工作要做。只需连接到所有这些,而对于无法联系的那些,让它失败。如果您不想看到错误,可以添加 -ErrorAction SilentlyContinue

$VMs = Invoke-Command -ComputerName Server1,Server2 -ScriptBlock { 
    Add-PsSnapin vmware.view.broker
    Get-DesktopVm 
} 

现在您拥有所有 VM,获取用户 enabled/disabled 状态

foreach ($VM in $VMs) {

    $Sid = $VM.user_sid

    $AdEnabled = Invoke-Command -ComputerName domaincontroller -ScriptBlock {
        (Get-AdUser -Identity $using:Sid).Enabled
    }

    $VM| Add-Member -NotePropertyName 'AdEnabled' -NotePropertyValue $AdEnabled

}

现在理想情况下,您应该将 $VM 作为对象数组,每个对象都具有所有 VM 桌面属性 - 以及该用户帐户的 True/False AD 启用状态 属性。

$VM | Out-Gridview

$VM | Export-Csv Report.csv

$VM | Where-Object { -not $_.AdEnabled }