CES
asked on
Get-TSSessions Powershell script works with single Computer Name, fails when I substitute a variable
My goal in this script to to take a CSV list of servers and find disconnected RDP sessions. I have gotten to the point where I have the server names into a variable ($tshosts below) and I can run my Get-TSSessions cmdlet to export to file in the format that I want.
My issue is that Once I subsitute my variable, the script does not seem to run. I'm hoping I can get a second set of eyes on this and help me see where I'm getting it wrong. Any help is much appreciated!
import-module ActiveDirectory
Import-Module PSTerminalServices
$serverlist = Import-Csv \\path\Computers.csv
$rdphosts=@()
foreach($server in $serverlist)
{
$rdphosts +=Get-ADComputer $server.Name
}
$tshosts=$rdphosts | Select -Property Name
foreach ($tshost in $tshosts){
If (Test-Connection $tshost -count 1 -quiet){
Get-TSSession -ComputerName $tshost -ErrorAction SilentlyContinue | Where-Object {$_.ConnectionState -eq 'Disconnected'} | select {$_.Server.ServerName},Con nectionSta te,UserAcc ount | Export-Csv c:\ps\finalresults.csv -NoTypeInformation
}
}
My issue is that Once I subsitute my variable, the script does not seem to run. I'm hoping I can get a second set of eyes on this and help me see where I'm getting it wrong. Any help is much appreciated!
import-module ActiveDirectory
Import-Module PSTerminalServices
$serverlist = Import-Csv \\path\Computers.csv
$rdphosts=@()
foreach($server in $serverlist)
{
$rdphosts +=Get-ADComputer $server.Name
}
$tshosts=$rdphosts | Select -Property Name
foreach ($tshost in $tshosts){
If (Test-Connection $tshost -count 1 -quiet){
Get-TSSession -ComputerName $tshost -ErrorAction SilentlyContinue | Where-Object {$_.ConnectionState -eq 'Disconnected'} | select {$_.Server.ServerName},Con
}
}
ASKER
Thank you the edits were quite helpful. Two things, however:
- The ISE is claiming that the final pipe for exporting to CSV is empty
It doesn't quite like how I am trying to pull the server name. it is giving me the following error:
The "e" key has a type, System.Management.Automati on.PSObjec t, that is not valid; expected types are {System.String, System.Management.Automati on.ScriptB lock}
If I get rid of the pipe/export and remove the search for server name, it loks to work great, so I think it's almost there....
- The ISE is claiming that the final pipe for exporting to CSV is empty
It doesn't quite like how I am trying to pull the server name. it is giving me the following error:
The "e" key has a type, System.Management.Automati
If I get rid of the pipe/export and remove the search for server name, it loks to work great, so I think it's almost there....
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I've implemented this script in my env.
function Get-PingStatus
{
[cmdletbinding()]
param(
[parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]
[Alias('Name','IP','IPAddress')]
[string]$Computer
)
$PingStatus = Get-WmiObject -Query "SELECT StatusCode FROM win32_PingStatus WHERE ADDRESS = '$Computer'"
if ($PingStatus.StatusCode -eq 0) {
$true
}
else
{
$false
}
} # END Get-PingStatus
###################
##### GLOBALS #####
###################
# Change the keyword to an OS search term such as Server
#$Filter = 'OperatingSystem -like "*Server*"'
# get all computers from Active Directory matching the defined keword
# $ServerList = Get-ADComputer -Properties Name -Filter $Filter | Select Name | Sort-Object -Property Name
#$ServerList = Get-ADComputer -Properties Name -Filter $Filter | Select Name | Sort-Object -Property Name
$ServerList = Get-Content C:\TS_Sessions\1030PMServers.txt
$OutputFile = "C:\TS_Sessions\1030PM.htm"
# Get domain name, date and time for report title
$DomainName = (Get-ADDomain).NetBIOSName
$Time = Get-Date -Format t
$CurrDate = Get-Date -UFormat "%D"
# Info for footer
$ServerTotal = ($ServerList).count
# Option to create transcript - change to $true to turn on.
$CreateTranscript = $false
# Option to send email - change to $true to turn on
$SendEmail = $True
# SMTP Settings
$smtpServer = "smtp.office365.com"
$SmtpUser = 'smtpuser'
$smtpPassword = "smtpuserpassword"
$From = "from"
$To = "to"
$cc = "cc"
$Subject = "10:30PM Shutdown - $DomainName RDP Sessions"
###############
##### PRE #####
###############
# Start Transcript if $CreateTranscript variable above is set to $true.
if($CreateTranscript)
{
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
if( -not (Test-Path ($scriptDir + "\Transcripts"))){New-Item -ItemType Directory -Path ($scriptDir + "\Transcripts")}
Start-Transcript -Path ($scriptDir + "\Transcripts\{0:yyyyMMdd}_Log.txt" -f $(get-date)) -Append
}
# Import modules - AD and PSTS which contains Get-TSSession
Import-Module ActiveDirectory
Import-Module PSTerminalServices
################
##### MAIN #####
################
$HTML = '<head>
<style>
table {
font-family: Segoe UI;
border-collapse: collapse;
width: 100%;
}
th {
border: 1px solid black;
background-color: #A8D3DA;
text-align: Center;
padding: 8px;
}
td{
border: 1px solid black;
text-align: left;
padding: 8px;
}
tr:nth-child(even) {
background-color: #dddddd;
}
</style>
</head> '
# Report Header
$Header = "<H2 align=center><font face='Segoe UI' size=4>$DomainName Servers ($ServerList) RDP Sessions as of $Time on $CurrDate (Server Time UTC +00:00)</font></H2>"
# Report Footer
$Footer = "<H4 align=center><font 'Segoe UI' size=3 Color=Blue>Pl. Note: If the report is empty, consider there is no active/disconnected sessions available in the server.</font></H4>"
$Footer += "<H5 align=center><font 'Segoe UI' size=3 Color=Blue>-= This is an Auto Generated Eamil =-</font></H5>"
$HTML += "<HTML><BODY><Table border=1 cellpadding=0 cellspacing=0 width=100% id=TSHead class=sortable>
<TR>
<TH><B>Server</B></TH>
<TH><B>User Name</B></TH>
<TH><B>Client Name</B></TD>
<TH><B>Client IP</B></TH>
<TH><B>Session State</B></TH>
<TH><B>Session Name</B></TH>
<TH><B>Login Time</B></TH>
<TH><B>Last Input Time</B></TH>
</TR>
"
ForEach ($ServerName in $ServerList)
{
If (Get-PingStatus $ServerName)
{
Try{
$TSSessions = Get-TSSession -ComputerName $ServerName -ErrorAction SilentlyContinue | Select UserAccount,ClientName,ClientIPAddress,State,WindowStationName,LastInputTime,LoginTime
}
Catch{
}
}
# Sessions where the username is blank and ICA (Citrix) sessions are excluded from the results
# To see every session, change the line below to ForEach($Session in $TSSessions)
# To include ICA sessions, change it to ForEach($Session in ($TSSessions | WHERE {$_.UserAccount -ne $null}))
ForEach($Session in ($TSSessions | WHERE {$_.UserAccount -ne $null -AND {$_.WindowStationName -notlike "*ICA*" -like "Services"}}))
{
$HTML += "<TR>
<TD>$($ServerName)</TD>
<TD>$($Session.UserAccount)</TD>
<TD>$($Session.ClientName)</TD>
<TD>$(($Session.ClientIPAddress).IPAddressToString)</TD>
<TD>$($Session.State)</TD>
<TD>$($Session.WindowStationName)</TD>
<TD>$($Session.LoginTime)</TD>
<TD>$($Session.LastInputTime)</TD>
</TR>"
}
}
$HTML += "<H2></Table></BODY></HTML>"
$Header + $HTML + $Footer | Out-File $OutputFile
# Send email if $SendEmail variable above is set to $true
if($SendEmail)
<#{
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $true
$message.Body = $OutputFile | ConvertTo-HTML -Head $HTML
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.EnableSsl = true;
$smtp.UseDefaultCredentials = false;
$smtp.Credentials = $Credentials;
$smtp.Send($message)
} #>
{
$Body = Get-Content $OutputFile -RAW
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SmtpUser, $($smtpPassword | ConvertTo-SecureString -AsPlainText -Force)
send-MailMessage -SmtpServer $smtpserver -To $to -cc $cc -From $from -Subject $subject -body $body -BodyAsHtml -UseSsl -Credential $Credentials
}
ASKER
In my editing, I moved one of the closing brackets off of the last line, which the script seemed to care about. I just ran it and it worked perfectly.
Thank you much!
Thank you much!
ASKER
In my editing, I moved one of the closing brackets off of the last line, which the script seemed to care about. I just ran it and it worked perfectly.
Thank you much!
Thank you much!
You can use -ExpandProperty to expand the respective property.
That said, this should work:
Open in new window