Kirklees and Calderdale Care Association
# =========================
# Config (Diet)
# =========================
$version = “Diet 1.4”
$timestamp = “25/09/2025”;

# =========================
# Helpers
# =========================
function showPassed { param($str); Write-Host “$([char]0x2713) $str” -ForegroundColor Green }
function showFailed { param($str); Write-Host “X $str” -ForegroundColor Red }
function showInfo { param($str); Write-Host $str -ForegroundColor Yellow }

# =========================
# Updates
# =========================
function checkWindowsUpdateService {
$service = Get-Service -Name “wuauserv” -ErrorAction SilentlyContinue
if ($service -and $service.Status -eq ‘Running’) { showPassed “Windows Update Service is running” } else { showFailed “Windows Update Service is not running” }
checkAutoUpdateSettings
checkRecentUpdateHistory
}
function checkAutoUpdateSettings {
$path = “HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU”
$cfg = Get-ItemProperty -Path $path -ErrorAction SilentlyContinue
if ($cfg -and $cfg.AUOptions -eq 4) { showPassed “Auto-update set to auto-install” }
elseif ($cfg -eq $null) { showPassed “No policy set (likely default Windows Update behaviour)” }
else { showFailed “Auto-update policy may not auto-install updates” }
}
function checkRecentUpdateHistory {
$lastMonth = (Get-Date).AddMonths(-1)
$q = “SELECT * FROM Win32_QuickFixEngineering WHERE InstalledOn >= ‘$($lastMonth.ToString(“MM/dd/yyyy”))'”
$updates = Get-WmiObject -Query $q
if ($updates) { showPassed “Updates found in the last month” } else { showFailed “No updates installed in the last month” }
}

# =========================
# BitLocker (explicit wording + one-time note)
# =========================
$script:__bitlockerNoteShown = $false

function encryptionTest { encryptionTestExternal ‘C:’ }
function encryptionTestExternal($d) {
if (-not $script:__bitlockerNoteShown) {
Write-Host “Note: This check looks for Microsoft BitLocker only (not third-party full disk encryption or Device Encryption on some Home editions).” -ForegroundColor Yellow
$script:__bitlockerNoteShown = $true
}

$state = (New-Object -ComObject Shell.Application).NameSpace($d).Self.ExtendedProperty(‘System.Volume.BitLockerProtection’)
Write-Host “BitLocker check on $d”
if (1 -eq $state -or 3 -eq $state) { showPassed “BitLocker is ON for $d” } else { showFailed “BitLocker is OFF for $d” }

if ((Read-Host “`r`Check another drive? (y/n)”) -match ‘^(y|yes)$’) {
$drive = Read-Host “Enter drive letter and colon (e.g. D:)”
encryptionTestExternal $drive
}
}

# =========================
# User privileges
# =========================
function userPrivilegesTest {
Write-Host “User Privileges:”
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).
IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if ($isAdmin) { showFailed “This account has administrator rights” } else { showPassed “This account is not an administrator” }
}

# =========================
# Anti-virus + EICAR
# =========================
function avTests {
Write-Host “Antivirus:”
$names = (Get-CimInstance -Namespace “root/SecurityCenter2” -ClassName AntiVirusProduct -ErrorAction SilentlyContinue |
Select-Object -ExpandProperty displayName) -join ‘, ‘
if ($names) { showPassed “AV detected: $names” } else { showFailed “No antivirus detected by SecurityCenter2” }
}
function eicarTests {
if ((Read-Host “`r`Run harmless EICAR test files? (y/n)”) -ne ‘y’) { return }

$urls = @(
‘https://www.eicar.org/download/eicar-com/?wpdmdl=8840&refresh=68d547aac57031758807978’, # Basic
‘https://www.eicar.org/download/eicar_com-zip/?wpdmdl=8847&refresh=68d547aeea35d1758807982’, # Zipped
‘https://www.eicar.org/download/eicar-com-2-2/?wpdmdl=8848&refresh=68d547b0e5bec1758807984’ # Double zipped
)
foreach ($u in $urls) {
Read-Host -Prompt “Press Enter for next test or CTRL+C to quit” | Out-Null
Start-Process $u | Out-Null # default browser
}
}

# =========================
# Password wallets (OG Edge + Chrome)
# =========================
function openWallet {
$confirmation = Read-Host “`r`Do you want to check passwords in Edge? (y/n)”
if ($confirmation -match ‘^(y|yes)$’) {
write-host “Opening Wallet to check password strength…”;
$url = “edge://wallet/passwords/checkup”;
Add-Type -AssemblyName System.Windows.Forms;
[System.Windows.Forms.Clipboard]::SetText($url)
Start-Process “msedge.exe”;
Start-Sleep -Seconds 4;
Add-Type -AssemblyName PresentationFramework;
[System.Windows.Forms.SendKeys]::SendWait("{F4}");
[System.Windows.Forms.SendKeys]::SendWait($url);
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}");
}
}
function chromeCheck {
# $chromeInstalled = (Get-Item (Get-ItemProperty ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe’ -ErrorAction SilentlyContinue).'(Default)’).VersionInfo
$chromePath = (Get-ItemProperty ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe’ -ErrorAction SilentlyContinue).'(default)’
$a = $false;
if ($chromePath) {
$chromeInstalled = (Get-Item $chromePath).VersionInfo.FileName
$a = $true;
}
return $a;
}
function chromePasswords {
$hasChrome = chromeCheck;
if ($hasChrome) {
Write-Host “Chrome installed.”;
}
if ($hasChrome -eq $false) {
Write-Host “Chrome not installed so skipping check”;
return;
}
$confirmation = Read-Host “`r`Do you want to check passwords in Chrome? (y/n)”;
if ($confirmation -match ‘^(y|yes)$’) {
write-host “Chrome Password Check”
Start-Sleep -Seconds 3;
$b = chromeCheck;
if ( $true -eq $b ) {
$url = “chrome://password-manager/checkup?start=true”;
Start-Process “chrome.exe” -ArgumentList ‘–profile-directory=”Default”‘;
Start-Sleep -Seconds 3;
Add-Type -AssemblyName PresentationFramework;
[System.Windows.Forms.SendKeys]::SendWait(“{F4}”);
[System.Windows.Forms.SendKeys]::SendWait($url);
[System.Windows.Forms.SendKeys]::SendWait(“{ENTER}”);
} else {
Write-Host “”;
showInfo(“No Chrome installed so skipping….”)
Write-Host “”;
}
}
}

# =========================
# Windows Firewall
# =========================
function windowsFirewall {
$profiles = Get-NetFirewallProfile -ErrorAction SilentlyContinue
if (-not $profiles) { showInfo “Could not read firewall profiles”; return }
Write-Host “Windows Firewall Profiles:” -ForegroundColor Yellow
foreach ($p in $profiles) {
if ($p.Enabled) { showPassed “Profile ‘$($p.Name)’ is ON” } else { showFailed “Profile ‘$($p.Name)’ is OFF” }
}
}
<#
If you’re reading this far, you’re my kind of nerd <3
⡎⠑ ⡀⢀ ⣇⡀ ⢀⡀ ⡀⣀ ⢎⡑ ⢀⣀ ⣀⣀
⠣⠔ ⣑⡺ ⠧⠜ ⠣⠭ ⠏ ⠢⠜ ⠣⠼ ⠇⠇⠇
Giraffes are 30 times more likely to get hit by lightning than people
#>
# =========================
# MFA (manual + passive signals)
# =========================
function Get-LocalPosture {
$ds = (dsregcmd /status) -join “`n”
$aadJoined = [bool]([regex]::Match($ds,’AzureAdJoined\s*:\s*(YES|NO)’,’IgnoreCase’).Groups[1].Value -eq ‘YES’)
$prtPresent = [bool]([regex]::Match($ds,’AzureAdPrt\s*:\s*(YES|NO)’,’IgnoreCase’).Groups[1].Value -eq ‘YES’)
$whfbFolder = Test-Path “$env:ProgramData\Microsoft\Ngc”
$upn = (& whoami /upn) 2>$null; $user = (& whoami) 2>$null
[pscustomobject]@{ Device=$env:COMPUTERNAME; User=$user; UPN=$upn; AADJoined=$aadJoined; PRTPresent=$prtPresent; WHFB=$whfbFolder }
}
function Write-ColouredLine([string]$Label,[string]$Value,[string]$Colour=”White”,[int]$PadWidth=40){
$pad=[math]::Max(1,$PadWidth-$Label.Length); $spacer=” ” * $pad
Write-Host -NoNewline ($Label+$spacer+”: “); Write-Host $Value -ForegroundColor $Colour
}
function MFACheck {
Write-Host “=== MFA Checks ===” -ForegroundColor Cyan

$manual = $null
if ((Read-Host “`r`Open Microsoft Security Info page? (y/n)”) -match ‘^(y|yes)$’) {
$edgePath = “${env:ProgramFiles(x86)}\Microsoft\Edge\Application\msedge.exe”
if (-not (Test-Path $edgePath)) { $edgePath = “${env:ProgramFiles}\Microsoft\Edge\Application\msedge.exe” }
if (Test-Path $edgePath) { Start-Process $edgePath https://mysignins.microsoft.com/security-info }
else { Start-Process https://mysignins.microsoft.com/security-info }
$ans = Read-Host “Do you see at least one strong MFA method (Authenticator app or FIDO2 key)? (Y/N/(U)nable to check)”
switch -Regex ($ans) {
‘^(y|yes)$’ { $manual = ‘Yes’ }
‘^(n|no)$’ { $manual = ‘No’ }
‘^(u|unable).*’ { $manual = ‘Unable to check due to account login’ }
default { $manual = ‘Unable to check due to account login’ }
}
}
$posture = $null
if ((Read-Host “Check passive MFA signals on this device? (y/n)”) -match ‘^(y|yes)$’) { $posture = Get-LocalPosture }

Write-Host “=== MFA Check Summary ===”
if ($posture) {
Write-ColouredLine “Device name” $posture.Device White
Write-ColouredLine “Current user” $posture.User White
Write-ColouredLine “User sign-in (UPN)” $posture.UPN White
if ($posture.AADJoined) { Write-ColouredLine “Device joined to Azure AD / MS Entra ID” “Yes” Green } else { Write-ColouredLine “Device joined to Azure AD / MS Entra ID” “No” Red }
if ($posture.PRTPresent){ Write-ColouredLine “Primary Refresh Token” “Present” Green } else { Write-ColouredLine “Primary Refresh Token” “Not present” Red }
if ($posture.WHFB) { Write-ColouredLine “Windows Hello configured” “Likely configured” Green } else { Write-ColouredLine “Windows Hello configured” “Not detected” Red }
}
if ($manual -eq ‘Yes’) { Write-ColouredLine “Manual check result” $manual Green }
elseif ($manual -eq ‘No’) { Write-ColouredLine “Manual check result” $manual Red }
elseif ($manual) { Write-ColouredLine “Manual check result” $manual Yellow }
else { Write-ColouredLine “Manual check result” “Not performed” Yellow }
}

# =========================
# Installed programs (lite, with plain-English explainer)
# =========================
function Get-InstalledPrograms {
$paths = @(
‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*’,
‘HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*’,
‘HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*’,
‘HKCU:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*’
)
$items = foreach ($p in $paths) { Get-ItemProperty -Path $p -ErrorAction SilentlyContinue }
$items |
Where-Object { $_.DisplayName } |
Select-Object @{n=’Name’;e={$_.DisplayName}},
@{n=’Version’;e={$_.DisplayVersion}},
@{n=’Publisher’;e={$_.Publisher}} |
Sort-Object Name, Version, Publisher -Unique
}
function installedProgsLite {
$confirm = Read-Host “`r`Check installed programs for security/management tools? (y/n)”
if ($confirm -notmatch ‘^(y|yes)$’) { return }

Write-Host “Note: Some organisations use tools like Full Disk Encryption (FDE), Remote Monitoring & Management (RMM), and Endpoint Detection & Response (EDR).” -ForegroundColor Yellow
Write-Host “These can centrally manage security and updates. If Windows Update or BitLocker looks OFF here, the device may still be protected by these tools.” -ForegroundColor Yellow

$programs = Get-InstalledPrograms

$keywords = @(
‘BitLocker’,’MBAM’,’WinMagic’,’SecureDoc’,’VeraCrypt’,’McAfee Drive Encryption’,’Symantec Endpoint Encryption’,
‘Sophos Device Encryption’,’SafeGuard’,’Check Point’,’Trend Micro’,’ESET Endpoint Encryption’,’Ivanti’,’Absolute’,
‘CrowdStrike’,’Carbon Black’,’SentinelOne’,’Defender for Endpoint’,’Kaspersky Endpoint’,’Bitdefender’,
‘Cisco AMP’,’Cisco Secure Endpoint’,’Tanium’,’N-able’,’N\-able’,’N-central’,’ConnectWise Automate’,’LabTech’,
‘Kaseya’,’NinjaRMM’,’Datto RMM’,’Atera’,’ManageEngine’,’Endpoint Central’,’Desktop Central’,
‘PDQ Deploy’,’PDQ Inventory’,’Dell Command’,’Dell Update’,’Lenovo System Update’,’HP Support Assistant’,’HP Wolf’
)
$pattern = ($keywords | ForEach-Object { [regex]::Escape($_) }) -join ‘|’

$hits = $programs | Where-Object { $_.Name -match $pattern -or $_.Publisher -match $pattern }

if ($hits) {
Write-Host “Possible security/management tools detected:” -ForegroundColor Yellow
$hits | Sort-Object Name | ForEach-Object {
Write-Host (” – {0} {1} ({2})” -f $_.Name, $_.Version, $_.Publisher)
}
} else {
Write-Host “No obvious security/management tools found.” -ForegroundColor Yellow
}

$showAll = Read-Host “`r`Show full installed programs list? (y/n)”
if ($showAll -match ‘^(y|yes)$’) {
Write-Host “Installed programs (Name — Version — Publisher):” -ForegroundColor Yellow
$programs | Sort-Object Name | ForEach-Object {
Write-Host (” – {0} — {1} — {2}” -f $_.Name, $_.Version, $_.Publisher)
}
}
}

# =========================
# Landing + run (landing stays visible)
# =========================
function Show-LandingPage {
Clear-Host
Write-Host “Welcome to the DCH Diet Script” -ForegroundColor Cyan
Write-Host “Using Version $version – Last Updated $timestamp” -ForegroundColor Yellow
Write-Host “Script written by Matthew Byfield – www.kircca.co.uk”
Write-Host “Edited by Cyber Sam – www.digitalcarehub.co.uk”
Write-Host “”
Write-Host “—- Testing System —-”
Write-Host “Press Enter to begin…” -ForegroundColor Yellow
Read-Host | Out-Null
Write-Host “”
Write-Host “Starting checks…” -ForegroundColor Cyan
runTests
}

function runTests {
encryptionTest
checkWindowsUpdateService
userPrivilegesTest
avTests
eicarTests
openWallet
chromePasswords
windowsFirewall
MFACheck
installedProgsLite
}

# Start
Show-LandingPage