从一个 PSSession 获取输入并将其发送到另一个
Taking input from one PSSession and sending it to another
与许多其他人一样,我的背景是 Linux,没有任何 Powershell 经验。所以这个面向对象的编程把我搞砸了。
我需要通过 VMware Horizon 搜索分配有用户的 VM,然后检查它们是否在 AD 中被禁用。如果它们在 AD 中被禁用,我想回收 VM。
目前我正在从 VMware Horizon 中提取用户的 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 }
与许多其他人一样,我的背景是 Linux,没有任何 Powershell 经验。所以这个面向对象的编程把我搞砸了。
我需要通过 VMware Horizon 搜索分配有用户的 VM,然后检查它们是否在 AD 中被禁用。如果它们在 AD 中被禁用,我想回收 VM。
目前我正在从 VMware Horizon 中提取用户的 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 }