PowerShell: Windows Session Memory Usage Watcher

# windowsSessionWatcher.ps1

$serverNames=@(
  'IRV-RDS01.domain1.net',
  'LAX-RDS02.domain2.com
)
$thresholdMemoryUsagePercent=30
$thresholdMemoryGb=20

$domainCreds=@(
    @{domain='domain1.ad';username='domain1\sysadmin';password=$env:pass1}
    @{domain='domain2.com';username='domain2\sysadmin';password=$env:pass2}
    )

# Email relay parameters
$emailFrom='sysadmins@kimconnect.com'
$emailTo='sysadmins@kimconnect.com'
$subject='High Memory Usage Sessions'
$smtpRelayServer='relay.testserver02.kimconnect.com'

function windowsSessionWatcher($thresholdPercent=10,$thresholdGb=20){
  $totalRam=Get-WMIObject -class win32_ComputerSystem | Select-Object -Expand TotalPhysicalMemory
  $processes=get-wmiobject win32_process 
  $users=$processes|select @{N='User';E={$_.getowner().user}}, WorkingSetSize|group user
  $memoryUsage=$users|select Name, `
    @{N='memoryMB';E={[math]::round(($_.Group.WorkingSetSize|Measure-Object -Sum).Sum/1MB,2)}}, `
    @{N='percent';E={[math]::round((($_.Group.WorkingSetSize|Measure-Object -Sum).Sum)/$totalRam*100,2)}} | `
    ?{$_.Name -notin 'SYSTEM',''} | `
    sort -property memoryMB -descending
  $overThreshold=$memoryUsage|?{$_.percent -ge $thresholdPercent -OR $_.memoryMB/1024 -ge $thresholdGb}
  if($overThreshold){
    return $overThreshold
  }else{
    write-host "There are no users consuming over $thresholdPercent percent OR $thresholdGb GB of $([math]::round($totalRam/1GB,2)) GB of system RAM "
  }
}

$results=@()
foreach ($serverName in $serverNames){  
  $serverDomain=$serverName.Substring($serverName.IndexOf(".")+1)
  $domainCred=$domainCreds|?{$_.domain -eq $serverDomain}
  write-host "Checking $serverName..."
  $adminUsername=$domainCred.username
  $adminPassword=$domainCred.password
  $encryptedPassword=ConvertTo-SecureString $adminPassword -AsPlainText -Force
  $adminCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $adminUsername,$encryptedPassword
  $psSession=try{new-pssession -computername $serverName -Credential $adminCred}catch{$false}
  if($psSession.State -eq 'Opened'){
    $result=invoke-command -session $psSession -scriptblock{
      param ($windowsSessionWatcher,$thresholdPercent,$thresholdMemoryGb)
      [scriptblock]::create($windowsSessionWatcher).invoke($thresholdPercent,$thresholdMemoryGb)
    } -Args ${function:windowsSessionWatcher},$thresholdMemoryUsagePercent,$thresholdMemoryGb
    $results+=$result
    Remove-PSSession $psSession
  }else{
    write-host "Unable to connect to $serverName..."
  }
}
$results=$results|select-object * -ExcludeProperty RunspaceId,PSShowComputerName

if($results.count){
  write-host "These users have matched the set thresholds:`r`n$($results|ft|out-string)" 
  $table=$results|ConvertTo-Html -Fragment -As Table
  $emailContent='<h1>'+$subject+'</h1>'+$table
  try{
    Send-MailMessage -From $emailFrom `
    -To $emailTo `
    -Subject $subject `
    -Body $emailContent `
    -BodyAsHtml `
    -SmtpServer $smtpRelayServer `
    -EA Stop
    write-host "Email has been set to $emailTo"
  }catch{
    write-warning $_
  }
}else{
  write-host "No user sessions have matched set thresholds"
}

Leave a Reply

Your email address will not be published. Required fields are marked *