Reputation: 21
I'm trying to write simple scripts to improve my powershell abilities, and I thought something I often do is drainstop our RDS servers to apply updates and such through server manager, or remote powershell sessions.
I've tried writing a script to do this based on my input, but no matter what I do, the contents of the variable isn't passed onto the remote server.
The script simply asks which server you wish to change, what state you wish to change it into, combines the value of the two, and passes it onto the remote server.
Alas... nothing. Code below. Any pointers would be greatly appreciated.
$SessionHosts = "Server_1", "Server_2", "Server_3", "Server_4"
$OpeningSalvo = Read-Host -Prompt "[Q]uery Servers or [C]hange State?"
If ($OpeningSalvo -match "q")
{
Invoke-Command $SessionHosts {chglogon.exe /query}
}
Elseif ($OpeningSalvo -match "c")
{
$Server = Read-Host -Prompt "Server Name?"
$State = Read-Host -Prompt "Enable, Drain, Drainuntilrestart or Disable"
$Run = "chglogon.exe /" + "$State"
#Invoke-Command -ComputerName $Server -ScriptBlock {Write-Host $Fun $using:Run echo $Fun}
#$ScriptBlockContent1 = {param ($Run) Write-Host $Run}
#Invoke-Command $Server $ScriptBlockContent1 -ArgumentList $Run
$ScriptBlockContent1 = {param ($Run) Write-Output $Run}
Invoke-Command $Server $ScriptBlockContent1 -ArgumentList $Run
$ScriptBlockContent2 = {Write-Host $Run}
Invoke-Command $Server $ScriptBlockContent2
}
Else
{
Write-Host "End"
}
I have managed to get this working using the following powershell script, but, it's a bit clumsy!
$SessionHosts = "Server_1", "Server_2", "Server_3", "Server_4"
$OpeningSalvo = Read-Host -Prompt "[C]hange State, [Q]uery Servers or [E]xit?"
If ($OpeningSalvo -match "q")
{
Invoke-Command $SessionHosts {chglogon.exe /query}
}
Elseif ($OpeningSalvo -match "c")
{
$Server = Read-Host -Prompt "Server Name?"
$State = Read-Host -Prompt "[1] Enable, [2] Drain, [3] Drain until restart, [4] Disable all connections"
If ($State -match "1")
{Invoke-Command $Server {chglogon.exe /enable}}
Elseif ($State -match "2")
{Invoke-Command $Server {chglogon.exe /drain}}
Elseif ($State -match "3")
{Invoke-Command $Server {chglogon.exe /drainuntilrestart}}
Elseif ($State -match "4")
{Invoke-Command $Server {chglogon.exe /disable}}
}
Else
{
Write-Host "End"
}
As an aside, the output of chglogon.exe /query in the first instance is a bit long winded.
Any suggestions for piping this into memory, and then pulling the server name and state out? I'm sure I can format it nicely.
In fact any suggestions at all would be appreciated! The more complicated and useful this script becomes, the more I'll learn! There might be errors, but this is my first script! :)
"Session logins are currently ENABLED + CategoryInfo : NotSpecified: (Session logins are currently ENABLED:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError + PSComputerName : Server2"
Upvotes: 2
Views: 578
Reputation: 6491
Without getting into the specifics of your problem, it looks like you're running into the issue of expanding external variables inside a script block.
If so, the solution isn't very pretty. I ran into this myself a while back, and the solution is to generate your script as a string first. That way, variables will be expanded. Then, you use the ScriptBlock static method Create()
to make a script block with your stuff expanded.
This blog - http://blogs.technet.com/b/heyscriptingguy/archive/2013/05/22/variable-substitution-in-a-powershell-script-block.aspx - gives an explanation, with an example of:
PS C:\> $a = "This is a string"
PS C:\> $b = "The value of `$a is $a"
PS C:\> $myScriptBlock = [ScriptBlock]::Create($b)
Upvotes: 2
Reputation: 7638
From this blog on how to replace chglogon.exe with powershell:
# Query
gwmi win32_terminalservicesetting -N "rootcimv2terminalservices" | %{
if ($_.logons -eq 1){"Disabled"}
else {
switch ($_.sessionbrokerdrainmode)
{
0 {"Enabled"}
1 {"DrainUntilRestart"}
2 {"Drain"}
default {"something’s not right here!"}
}
}
}
# Change logon /Enable
$temp = (gwmi win32_terminalservicesetting -N "rootcimv2terminalservices")
$temp.sessionbrokerdrainmode=0
$temp.logons=0
$temp.put()
# Change Logon /Disable
$temp = (gwmi win32_terminalservicesetting -N "rootcimv2terminalservices")
$temp.logons=1
$temp.put()
# Change Logon /Drain
$temp = (gwmi win32_terminalservicesetting -N "rootcimv2terminalservices")
$temp.sessionbrokerdrainmode=2
$temp.put()
# Change Logon /DrainUntilRestart
$temp = (gwmi win32_terminalservicesetting -N "rootcimv2terminalservices")
$temp.sessionbrokerdrainmode=1
$temp.put()
Combine this with the -Computer
param on gwmi
and you're chglogon replacement is good to go.
Upvotes: 1