ITsupport1066

Rotate SC machine keys

Mar 30th, 2026 (edited)
534
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #region Configuration
  2. $ConfigPath = "C:\Program Files (x86)\ScreenConnect\web.config"
  3. $LogPath = "C:\Logs\ScreenConnect-MachineKeyRotation"
  4. $LogFile = "$LogPath\KeyRotation_$(Get-Date -Format 'yyyyMMdd_HHmmss').log"
  5. $DisableOutOfHours = $true
  6. $OutofHoursStart = 20 # 8pm
  7. $OutofHoursEnd = 8    # 8am
  8.  
  9. #region Logging Function
  10. function Write-Log {
  11.     param (
  12.         [string]$Message,
  13.         [ValidateSet("INFO", "WARN", "ERROR", "SUCCESS")]
  14.         [string]$Level = "INFO"
  15.     )
  16.     $Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
  17.     $LogEntry = "[$Timestamp] [$Level] $Message"
  18.     # Write to screen with colour
  19.     switch ($Level) {
  20.         "INFO"    { Write-Host $LogEntry -ForegroundColor Cyan }
  21.         "WARN"    { Write-Host $LogEntry -ForegroundColor Yellow }
  22.         "ERROR"  { Write-Host $LogEntry -ForegroundColor Red }
  23.         "SUCCESS" { Write-Host $LogEntry -ForegroundColor Green }
  24.     }
  25.     # Write to log file
  26.     Add-Content -Path $LogFile -Value $LogEntry
  27. }
  28. #endregion
  29.  
  30. #region Ensure Log Directory Exists
  31. if (-not (Test-Path $LogPath)) {
  32.     New-Item -ItemType Directory -Path $LogPath -Force | Out-Null
  33.     Write-Log "Created log directory: $LogPath"
  34. }
  35. #endregion
  36.  
  37. # Check if $DisableOutOfHours is enabled and the current time is outside business hours. If so shutdown (and disable) the SC services and exit gracefully.
  38.  
  39. $currentHour = (Get-Date).Hour
  40.  
  41. $services = Get-Service -Name "ScreenConnect*"
  42.  
  43. if ($DisableOutOfHours -and ($currentHour -ge $OutofHoursStart -or $currentHour -lt $OutofHoursEnd)) {
  44.  
  45.     Write-Log "Out of hours detected. Stopping ScreenConnect services."
  46.     Write-Host "Out of hours detected. Stopping ScreenConnect services."
  47.  
  48.     foreach ($svc in $services) {
  49.  
  50.         if ($svc.Status -ne "Stopped") {
  51.             Write-Log "Stopping service:  $svc.Name"
  52.             Stop-Service -Name $svc.Name -Force
  53.         }
  54.  
  55.         Write-Log "Disabling service: $svc.Name"
  56.         Set-Service -Name $svc.Name -StartupType Disabled
  57.     }
  58.  
  59.     return
  60. }
  61. else {
  62.  
  63.     Write-Log "Business hours detected. Ensuring ScreenConnect services are running."
  64.     Write-Host "Business hours detected. Ensuring ScreenConnect services are running."
  65.  
  66.     foreach ($svc in $services) {
  67.  
  68.         Write-Log "Enabling service:  $svc.Name"
  69.         Set-Service -Name $svc.Name -StartupType Automatic
  70.  
  71.         if ($svc.Status -ne "Running") {
  72.             Write-Log "Starting service:  $svc.Name"
  73.             Start-Service -Name $svc.Name
  74.         }
  75.     }
  76. }
  77.  
  78. # If not out of business hours, start the rotation process, which will also stop and start the services as part of the procedure.
  79.  
  80.  
  81.  
  82. Write-Log "=========================================="
  83. Write-Log "  ScreenConnect MachineKey Rotation Start"
  84. Write-Log "=========================================="
  85. Write-Log "Config path: $ConfigPath"
  86. Write-Log "Log file:    $LogFile"
  87.  
  88. function Generate-MachineKey {
  89.     [CmdletBinding()]
  90.     param (
  91.         [ValidateSet("AES", "DES", "3DES")]
  92.         [string]$DecryptionAlgorithm = "AES",
  93.         [ValidateSet("HMACSHA256", "HMACSHA384", "HMACSHA512")]
  94.         [string]$ValidationAlgorithm = "HMACSHA256"
  95.     )
  96.  
  97.     function Convert-BytesToHex {
  98.         param ([byte[]]$Bytes)
  99.         $builder = New-Object System.Text.StringBuilder
  100.         foreach ($b in $Bytes) {
  101.             [void]$builder.AppendFormat("{0:X2}", $b)
  102.         }
  103.         return $builder.ToString()
  104.     }
  105.  
  106.     #region Decryption Key
  107.     switch ($DecryptionAlgorithm) {
  108.         "AES" { $crypto = [System.Security.Cryptography.Aes]::Create() }
  109.         "DES" { $crypto = [System.Security.Cryptography.DES]::Create() }
  110.         "3DES" { $crypto = [System.Security.Cryptography.TripleDES]::Create() }
  111.     }
  112.     $crypto.GenerateKey()
  113.     $DecryptionKey = Convert-BytesToHex -Bytes $crypto.Key
  114.     $crypto.Dispose()
  115.     #endregion
  116.  
  117.     #region Validation Key
  118.     switch ($ValidationAlgorithm) {
  119.         "HMACSHA256" { $hmac = [System.Security.Cryptography.HMACSHA256]::new() }
  120.         "HMACSHA384" { $hmac = [System.Security.Cryptography.HMACSHA384]::new() }
  121.         "HMACSHA512" { $hmac = [System.Security.Cryptography.HMACSHA512]::new() }
  122.     }
  123.     $ValidationKey = Convert-BytesToHex -Bytes $hmac.Key
  124.     $hmac.Dispose()
  125.     #endregion
  126.  
  127.     return @{
  128.         DecryptionKey = $DecryptionKey
  129.         ValidationKey = $ValidationKey
  130.     }
  131. }
  132.  
  133. #region Read Old Keys
  134. Write-Log "------------------------------------------"
  135. Write-Log "Reading existing keys from config..."
  136. try {
  137.     [xml]$xml = Get-Content $ConfigPath -ErrorAction Stop
  138.     $machineKey = $xml.configuration.'system.web'.machineKey
  139.     $OldValidationKey = $machineKey.validationKey
  140.     $OldDecryptionKey = $machineKey.decryptionKey
  141.     Write-Log "Old ValidationKey : $OldValidationKey"
  142.     Write-Log "Old DecryptionKey : $OldDecryptionKey"
  143. } catch {
  144.     Write-Log "Failed to read config file: $_" -Level "ERROR"
  145.     exit 1
  146. }
  147. #endregion
  148.  
  149. #region Generate New Keys
  150. Write-Log "------------------------------------------"
  151. Write-Log "Generating new machine keys..."
  152. try {
  153.     $NewKeys = Generate-MachineKey
  154.     $NewValidationKey = $NewKeys.ValidationKey
  155.     $NewDecryptionKey = $NewKeys.DecryptionKey
  156.     Write-Log "New ValidationKey : $NewValidationKey" -Level "SUCCESS"
  157.     Write-Log "New DecryptionKey : $NewDecryptionKey" -Level "SUCCESS"
  158. } catch {
  159.     Write-Log "Failed to generate new keys: $_" -Level "ERROR"
  160.     exit 1
  161. }
  162. #endregion
  163.  
  164. #region Stop Services
  165. Write-Log "------------------------------------------"
  166. Write-Log "Stopping ScreenConnect services..."
  167. try {
  168.     Get-Service -Name "ScreenConnect*" | ForEach-Object {
  169.         Write-Log "Stopping service: $($_.Name) (current status: $($_.Status))"
  170.     }
  171.     Get-Service -Name "ScreenConnect*" | Stop-Service -Force -ErrorAction SilentlyContinue
  172.     Start-Sleep -Seconds 5
  173.     while (Get-Service -Name "ScreenConnect*" | Where-Object { $_.Status -ne 'Stopped' }) {
  174.         Write-Log "Waiting for services to stop..." -Level "WARN"
  175.         Start-Sleep -Seconds 1
  176.     }
  177.     Write-Log "All ScreenConnect services stopped." -Level "SUCCESS"
  178. } catch {
  179.     Write-Log "Error stopping services: $_" -Level "ERROR"
  180.     exit 1
  181. }
  182. #endregion
  183.  
  184. #region Update Config
  185. Write-Log "------------------------------------------"
  186. Write-Log "Updating web.config with new keys..."
  187. try {
  188.     $machineKey.validationKey = $NewValidationKey
  189.     $machineKey.decryptionKey = $NewDecryptionKey
  190.     $xml.Save($ConfigPath)
  191.     Write-Log "web.config saved successfully." -Level "SUCCESS"
  192. } catch {
  193.     Write-Log "Failed to save web.config: $_" -Level "ERROR"
  194.     exit 1
  195. }
  196. #endregion
  197.  
  198. #region verfiy Config Update
  199. Write-Log "------------------------------------------"
  200. Write-Log "Verifying config update..."
  201. try {
  202.     [xml]$verifyXml = Get-Content $ConfigPath -ErrorAction Stop
  203.     $verifyMachineKey = $verifyXml.configuration.'system.web'.machineKey
  204.     if ($verifyMachineKey.validationKey -eq $NewValidationKey -and $verifyMachineKey.decryptionKey -eq $NewDecryptionKey) {
  205.         Write-Log "Config verification successful. Keys updated correctly." -Level "SUCCESS"
  206.     } else {
  207.         Write-Log "Config verification failed. Keys do not match expected values." -Level "ERROR"
  208.         exit 1
  209.     }
  210. } catch {
  211.     Write-Log "Failed to verify config update: $_" -Level "ERROR"
  212.     exit 1
  213. }
  214. #endregion
  215.  
  216. #region Start Services
  217. Write-Log "------------------------------------------"
  218. Write-Log "Starting ScreenConnect services..."
  219. try {
  220.     Get-Service -Name "ScreenConnect*" | Start-Service -ErrorAction SilentlyContinue
  221.     Start-Sleep -Seconds 5
  222.     while (Get-Service -Name "ScreenConnect*" | Where-Object { $_.Status -ne 'Running' }) {
  223.         Write-Log "Waiting for services to start..." -Level "WARN"
  224.         Start-Sleep -Seconds 1
  225.     }
  226.     Get-Service -Name "ScreenConnect*" | ForEach-Object {
  227.         Write-Log "Service running: $($_.Name) (status: $($_.Status))" -Level "SUCCESS"
  228.     }
  229. } catch {
  230.     Write-Log "Error starting services: $_" -Level "ERROR"
  231.     exit 1
  232. }
  233. #endregion
  234.  
  235. Write-Log "=========================================="
  236. Write-Log "  MachineKey rotation completed successfully"
  237. Write-Log "=========================================="
  238.  
Advertisement
Comments
  • User was banned
Add Comment
Please, Sign In to add comment