The Backstory
Imagine you’re navigating the complex corridors of a large IT enterprise, where every resource is meticulously controlled from a central point and you’re far removed from that central point. This story will resonate if you’ve experienced similar environments.
My task seemed simple enough: Notify users with computers flagged as vulnerable (based on their CVSS scores) that they’ve been quarantined. You might be thinking, “Just email them based off their vulnerability score!” But let’s face it, emails are often overlooked or ignored. “What about isolating them in a restricted VLAN?” Good thought, but impractical – we can’t risk hampering their work. We’re treading a fine line, accepting the risk of these vulnerable machines on the network but needing them remediated quickly. “Why not use an automated compliance tool like Microsoft SCCM?” Ah, if only it were that simple! Our hands are tied by upper management’s control and their reluctance to delegate such powers.
Long story short, the following script is the workaround that I created to notify users of their computers impending quarantine via a wallpaper change. A big lesson learned in writing it was the use of registry hives – I didn’t realize individual profiles had their registry settings stored in their user directory as the NTUSER.dat.
The Script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
# Enhanced PowerShell Script for Quarantine Notification via Wallpaper Change
# Define constants
$filename = "C:\temp\quarantine-notice.png"
$computerName = "TARGET-COMPUTER-NAME" # Replace with dynamic retrieval or input
$fontFamily = 'Consolas'
$fontSize = 18
$backgroundColor = [System.Drawing.Color]::Purple
$foregroundColor = [System.Drawing.Color]::White
$message = "Your computer has been quarantined. Please contact IT Support at ###-#### ([email protected])"
$imageWidth = 1024
$imageHeight = 768
$registryPathCurrentUser = "Registry::HKEY_CURRENT_USER\Control Panel\Desktop"
$registryPathTemp = "Registry::HKEY_USERS\Temp\Control Panel\Desktop"
# Create the notification image
function Create-NotificationImage {
$bmp = New-Object System.Drawing.Bitmap $imageWidth, $imageHeight
$font = New-Object System.Drawing.Font $fontFamily, $fontSize
$brushBg = New-Object System.Drawing.SolidBrush $backgroundColor
$brushFg = New-Object System.Drawing.SolidBrush $foregroundColor
$graphics = [System.Drawing.Graphics]::FromImage($bmp)
$graphics.FillRectangle($brushBg, 0, 0, $bmp.Width, $bmp.Height)
# Center text
$size = $graphics.MeasureString($message, $font)
$textX = ($bmp.Width - $size.Width) / 2
$textY = ($bmp.Height - $size.Height) / 2
# Draw the text
$graphics.DrawString($message, $font, $brushFg, $textX, $textY)
$bmp.Save($filename)
$graphics.Dispose()
}
# Apply wallpaper to each user profile
function Apply-WallpaperToUsers {
$users = Get-ChildItem "$env:SystemDrive\Users"
foreach ($user in $users) {
$hiveLoaded = $false
$dir = $registryPathCurrentUser
if ($user.Name -ne $env:username -and $user.PSIsContainer) {
reg.exe LOAD HKU\Temp "$env:SystemDrive\Users\$($user.Name)\NTUSER.DAT" 2>$null
if (Test-Path $registryPathTemp) {
$dir = $registryPathTemp
$hiveLoaded = $true
}
}
if (Test-Path $dir) {
Set-ItemProperty -Path $dir -Name "Wallpaper" -Value "$filename"
}
if ($hiveLoaded) {
[gc]::Collect()
reg.exe UNLOAD HKU\Temp 2>$null
}
}
}
# Main
Create-NotificationImage
Apply-WallpaperToUsers
# This logs off everyone on the target computer -- Not necessary if you're running this script at night
# Invoke-Expression -Command “logoff.exe console" # TODO: find a way to immediately refresh without logging off > "RUNDLL32.EXE USER32.DLL, UpdatePerUserSystemParameters, True" and restarting explorer.exe aren't consistent
|