I read the answer here : Various_Scripts/remove_faulty_VDI_desktop.ps1 at master · Magneet/Various_Scripts · GitHub
Is there a way, not to remove of delete the Agent_Unreachable machine but to just try a desktop refresh or the equivalent, without doing a Connect-VIServer, but using only the HV server connection?
I have tried many of the API commands of this nature but can not seem to find a way to do this without a VIServer connection.
Is it possible? Has anyone done it? Would you be willing to share a snippet of your code to guide me.
I have been able to get-hvsummary for each Pool, using -State Unreachable.
Basically, my VMware sysadmins believe this is possible and I am tryng to write the code. I have looked at many calls in the API but get message like "You need a connection to VI Server."
I have a script making a list of machines in an unreachable state...and then 15 minutes later, by writing results to files and reading previous file back in again....if machine is still unreachable 15 minutes later I want to do whatever is equivalent to a Desktop_Refresh. I have machineids etc.
Peg Duffy
*Updated the script slightly.*
https://get-cj.com/2018/04/02/how-to-refresh-vmware-horizon-desktops-using-powershell-powercli/
I was inspired by pegduffy after you posted that snippet of code. I wrote a new function that refreshes a desktop or a list of desktops. Much of the reference for this comes from the various VMWare sites and Horizon API reference pages. Please post your solution as well when you find it. If you want It's good to see the way others do it. Good learning experience.
Example:
$machines = ('machinename1', 'machinename2')
refresh-ViewDesktop -machines $machines -viewserver 'Horizon_Connection_Server'
function refresh-ViewDesktop {
[CmdletBinding()]
[OutputType([PSCustomObject])]
param(
[string[]]$machines,
[string]$viewserver
)
$cred = Get-Credential
$hvServer = Connect-HVServer -server $viewserver -Credential $cred
$hvServices = $hvServer.ExtensionData
$queryService = New-Object VMware.Hv.QueryServiceService
$query = New-Object VMware.Hv.QueryDefinition
$query.queryEntityType = 'MachineNamesView'
[VMware.Hv.QueryFilter []] $filters = @()
foreach ($machine in $machines){
$filters += new-object VMware.Hv.QueryFilterEquals -property @{'memberName' = 'base.name'; 'value' = $machine}
}
$orFilter = new-object VMware.Hv.QueryFilterOr -property @{'filters' = $filters}
$query.Filter = $orFilter
$queryResults = $queryService.QueryService_Create($hvServices,$query)
$finalmachine = @()
foreach ($result in $queryResults.Results){
[VMware.Hv.MachineNamesView]$machineNamesView = $result
$properties = @{
machineid = $machineNamesView.id
names = $machineNamesView.base.name
desktopId = $machineNamesView.base.Desktop
}
$finalmachine += New-Object -TypeName pscustomobject -Property $properties
}
$desktopService = New-Object VMware.Hv.DesktopService
$machineService = New-Object VMware.Hv.MachineService
foreach($object in $finalmachine){
$desktoprefreshSpec = New-Object VMware.Hv.DesktopRefreshSpec
$desktoprefresheSpecHelper = New-Object VMware.Hv.DesktopService+DesktopRefreshSpecHelper
$desktoprefreshSpec.Machines = $object.machineid
$desktoprefreshSpec.LogoffSetting = $desktoprefresheSpecHelper.LOGOFF_SETTING_FORCE_LOGOFF
$desktoprefreshSpec.StartTime = $null
$desktopService.Desktop_Refresh($hvServices, $machineNamesView.base.Desktop,$desktoprefreshSpec)
Write-Output ""
Write-Output "Refreshing Machines"
$($object.names)
}
}
Disclaimer: ~I'm just an IT enthusiast with no certs, no degrees, no training, in any of this crap, but I know my way around google so that's all that matters. -Jose Rodriguez~
Why are your VMWare admins not writing this script? Anyway. I had a few minutes and thought this would be be helpful to you:
You'l need this PowerCLI-Example-Scripts/Modules/VMware.Hv.Helper at master · vmware/PowerCLI-Example-Scripts · GitH...
This gives you the full arsenal of the Horizon API and the vmware.view.broker snapin from the Horizon server in case you want to do other things.
You could also replace, from line 31, the Send-VDIVMReset with Send-VDILinkedCloneRefresh for example if you needed to do a refresh instead of a reset and so on.
You're welcome
#Jose Rodriguez
$viewserver = "NAME_OF_VIEW_SERVER"
if($cred -eq $null){
$cred = Get-Credential
}
if($connect -eq $null){
$connect = Connect-HVServer -server $viewserver -Credential $cred
}
$session = New-PSSession -Computername $viewserver
$scriptBlock = {
Add-PSSnapin vmware.view.broker
}
#Run the script block on the connection server. $argument1 will become $computer in the scriptblock and so forth
Invoke-Command -Session $session -ScriptBlock $scriptBlock
Import-PSSession -Session $session -Prefix VDI -Module VMware*
(Get-HVMachine -PoolName NAME_OF_POOL).base | where {$_.basicstate -eq 'AGENT_UNREACHABLE'} | foreach { Get-VDIDesktopVM -Name $_.name | Send-VDIVMReset -id $_.id }
Remove-PSSession $session
~I'm just an IT enthusiast with no certs, no degrees, no training, in any of this crap, but I know my around google so that's all that matters. -Jose Rodriguez~
can be done certainly, have written it out on my blog: https://www.retouw.nl/powercli/removing-faulty-horizon-desktops-using-powercli/
I see I might need to change it so it doesn't use the vmware.hv.helper (needs lots of improvements, working on that) and you can choose to remove or reset, just comment the right line out
Jose,
Thanks so much for your answer. I am sorry I steered you wrong. I am using Horizon 7 Version 7.2 so I can not use snap-ins. The commandlets you are using are no longer available.
No Send-VDILinkedCloneRefresh in this version. Just the View API - VMware API Explorer - VMware {code}
I would like to do what is on the View Horizon Admin Center Version 7 as
Catalog -> Desktop Pools -> Select one of the Pools....-> Look at Inventory of Machines -> Select one -> View Composer -> Refresh
So the previous Send-VDILinkedCloneRefresh is probably what I needed prior to this version.
I am using VMWare.Hv.Helper....but no equivalent commandlets there that I can tell.
Magneet,
I do not want to delete the machine. I want to Refresh it only.
Is it possible to do this using only a connection to an HVserver....Connect-HVServer but not using a Connect-VIServer?
I did see your code and you solution. Perhaps what I am attempting is not possible.
Do you know?
Interested parties,
It took a bit of browsing git hub....but I think
I just found code on github that may have the snippet I need.
GitHub - cjrege/HorizonView: VMware Horizon View PowerShell Module
Specifically see function Invoke-ViewComposerTask
And in that function:
if ($Refresh){ | |
$refreshSpec = New-Object VMware.Hv.DesktopRefreshSpec | |
$refreshSpecHelper = New-Object VMware.Hv.DesktopService+DesktopRefreshSpecHelper | |
switch ($LogOffSetting){ | |
"WAIT_FOR_LOGOFF" { | |
$refreshSpec.LogoffSetting = $refreshSpecHelper.LOGOFF_SETTING_WAIT_FOR_LOGOFF | |
} | |
"FORCE_LOGOFF" { | |
$refreshSpec.LogoffSetting = $refreshSpecHelper.LOGOFF_SETTING_FORCE_LOGOFF | |
} | |
default { | |
throw "Logoff setting not permitted" | |
} | |
} | |
if ($StartTime){ | |
$refreshSpec.StartTime = $StartTime | |
} | |
if ($StartNow){ | |
$refreshSpec.StartTime = (Get-Date).AddMinutes(1) | |
} | |
$refreshSpec.Machines = $machines.Id | |
$refreshSpec.StopOnFirstError = $StopOnFirstError | |
# Execute refresh | |
Write-Host Refreshing $desktopPool.Base.Name -ForegroundColor Cyan | |
$desktopService.Desktop_Refresh($HvServices, $desktopPoolId, $refreshSpec) | |
} |
Don't know why this was pasted into a table...but here you can see the code above that should refresh the desktop using machine id
Written by user cjrege. I am going to try now. Thanks to all and will post when I solve this.
*Updated the script slightly.*
https://get-cj.com/2018/04/02/how-to-refresh-vmware-horizon-desktops-using-powershell-powercli/
I was inspired by pegduffy after you posted that snippet of code. I wrote a new function that refreshes a desktop or a list of desktops. Much of the reference for this comes from the various VMWare sites and Horizon API reference pages. Please post your solution as well when you find it. If you want It's good to see the way others do it. Good learning experience.
Example:
$machines = ('machinename1', 'machinename2')
refresh-ViewDesktop -machines $machines -viewserver 'Horizon_Connection_Server'
function refresh-ViewDesktop {
[CmdletBinding()]
[OutputType([PSCustomObject])]
param(
[string[]]$machines,
[string]$viewserver
)
$cred = Get-Credential
$hvServer = Connect-HVServer -server $viewserver -Credential $cred
$hvServices = $hvServer.ExtensionData
$queryService = New-Object VMware.Hv.QueryServiceService
$query = New-Object VMware.Hv.QueryDefinition
$query.queryEntityType = 'MachineNamesView'
[VMware.Hv.QueryFilter []] $filters = @()
foreach ($machine in $machines){
$filters += new-object VMware.Hv.QueryFilterEquals -property @{'memberName' = 'base.name'; 'value' = $machine}
}
$orFilter = new-object VMware.Hv.QueryFilterOr -property @{'filters' = $filters}
$query.Filter = $orFilter
$queryResults = $queryService.QueryService_Create($hvServices,$query)
$finalmachine = @()
foreach ($result in $queryResults.Results){
[VMware.Hv.MachineNamesView]$machineNamesView = $result
$properties = @{
machineid = $machineNamesView.id
names = $machineNamesView.base.name
desktopId = $machineNamesView.base.Desktop
}
$finalmachine += New-Object -TypeName pscustomobject -Property $properties
}
$desktopService = New-Object VMware.Hv.DesktopService
$machineService = New-Object VMware.Hv.MachineService
foreach($object in $finalmachine){
$desktoprefreshSpec = New-Object VMware.Hv.DesktopRefreshSpec
$desktoprefresheSpecHelper = New-Object VMware.Hv.DesktopService+DesktopRefreshSpecHelper
$desktoprefreshSpec.Machines = $object.machineid
$desktoprefreshSpec.LogoffSetting = $desktoprefresheSpecHelper.LOGOFF_SETTING_FORCE_LOGOFF
$desktoprefreshSpec.StartTime = $null
$desktopService.Desktop_Refresh($hvServices, $machineNamesView.base.Desktop,$desktoprefreshSpec)
Write-Output ""
Write-Output "Refreshing Machines"
$($object.names)
}
}
Disclaimer: ~I'm just an IT enthusiast with no certs, no degrees, no training, in any of this crap, but I know my way around google so that's all that matters. -Jose Rodriguez~
I agree on jrodsguitar's solution but it's stupid that the spec is required that only makes it more complicated
pegduffy & jrodsguitar you guys want to put this in the vmware.hv.helper module? Could do it as well myself for you based on your work
Magneet,
Please feel free to use any of my code. And thank you for the hv.helper module. I suspect you tcan integrate the code better than I into that module. I have used the module in my code as you see and thank you again for that.
I am now testing my code in a test environment by putting test machines in unreachable_agent state - basically logging into a specific desktop and killing of the Agent service, - and then refreshing them (my test environment is isolated into a single pool specific test pool). I have tested a bit before posting so the code works for me. Please enjoy. Nice to be able to "pay it forward".
Thanks to you, cjrege, and jrodsguitar!
Yes that would be cool. I've learned so much from the community so giving back is not a problem
not sure when but I will definitely try to get this into the module, I am also just a contributor to it by the way. Untill now I only fixed or found a few bugs but have a couple of new functions & fixes waiting for a commit