Taking input from one PSSession and sending it to another

╄→尐↘猪︶ㄣ 提交于 2019-12-24 19:33:51

问题


Like many others, my background is in Linux with no powershell experience. So this object oriented programming is messing me up.

I need to search through VMware Horizon for VMs with users assigned to them, then check if they are disabled in AD. If they are disabled in AD I want to recycle the VM.

At the moment I am pulling the SIDs for the users from VMware Horizon, but when I try to use these in an invoke-command against AD I receive the following error

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

The Script so far

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}

回答1:


So this object oriented programming is messing me up.

So you're trying to revert to shell script, and writing twice as much code to do achieve half as much work.

The most important bit you're missing is to imagine an object as a collection of things - like, imagine you're working with /etc/passwd and each line has a user ID and a group ID and a home directory and a login shell.. and you're passing the entire line around at once, that's your analogous object.

An object has many properties, just like that (but overall more capable).

When you Select user_sid you're choosing that field to stay in the 'line', but the line is still something like :::user_sid:::: with the other fields now empty. (Approximately). But they're still there and in the way. To work with it directly, you have to get it out of the 'line' entirely - throw the container away and just have the user_sid outside of it.

get-desktopvm | select user_sid

->

get-desktopvm | select -expandproperty user_sid

which makes "sid1", "sid2", "sid3", but no containers for each sid.


This

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

is essentially saying

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

Because the function returns nothing, and it doesn't change any data on disk or anything, so when the function finishes, the variables are cleared out of memory, and you can't use them afterwards.


This:

if ($test -eq "True"){

is a bit of a nonsense. It might work, but it's not working how you expect because it's happenstance that "a string with content" compared to a boolean True is True, regardless of the string containing the English word "True" or not. But it's also redundant - $test is itself true or false, you don't need to compare True with anything. if ($test). Or even if (Test-Connection -ComputerName $vdi -Quiet)


But stillll, so much work. Just connect to them all, and let it fail for the ones it can't contact. Maybe add -ErrorAction SilentlyContinue if you don't want to see the error.

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

Now you have all the VMs, get the user enabled/disabled state

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

}

Now you should ideally have $VM as an array of objects, each one having all the VM Desktop properties - and also the True/False state of the AD Enabled property for that user account.

$VM | Out-Gridview

or

$VM | Export-Csv Report.csv

or

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


来源:https://stackoverflow.com/questions/44685595/taking-input-from-one-pssession-and-sending-it-to-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!