A PowerShell-based security compliance checker for Windows workstations.
IsItAllowed performs comprehensive security checks against your Windows workstation and reports compliance status with actionable remediation steps.
- 17 security checks covering encryption, network, authentication, and system configuration
- Three output formats: Console, JSON, HTML
- Configurable policies via JSON configuration file
- Remediation guidance with PowerShell commands for each failure
- Exit codes for CI/CD and automation integration
- No installation required - single script deployment
- Windows 10 or Windows 11
- PowerShell 5.1 or later
- Some checks require administrator privileges (BitLocker, SMBv1)
# Basic compliance check
.\IsItAllowed.ps1
# Generate HTML report
.\IsItAllowed.ps1 -OutputFormat HTML > compliance-report.html
# JSON output for SIEM integration
.\IsItAllowed.ps1 -OutputFormat JSON
# Use custom policy settings
.\IsItAllowed.ps1 -ConfigFile .\policy.json
# Verbose output to see what's being checked
.\IsItAllowed.ps1 -VerboseThese issues must be resolved for the device to be considered compliant.
| Check | Description | Risk |
|---|---|---|
| Firewall | All profiles (Domain/Public/Private) must be enabled | Network exposure |
| Local Admin | Current user should not be a local administrator | Privilege escalation |
| Vulnerable Ports | Ports 21, 22, 23, 25, 3389 should not be listening | Remote exploitation |
| BitLocker | System drive must be encrypted | Data theft |
| SMBv1 | Legacy SMB protocol must be disabled | WannaCry/EternalBlue |
| Secure Boot | UEFI Secure Boot must be enabled | Rootkit protection |
| UAC | User Account Control must be enabled | Privilege escalation |
| Guest Account | Guest account must be disabled | Unauthorized access |
| Auto-login | Automatic login must be disabled | Credential exposure |
These issues should be addressed but don't block compliance.
| Check | Description | Default Threshold |
|---|---|---|
| Windows Version | OS version should be supported by Microsoft | Current supported versions |
| Warning Ports | Ports 53, 80, 443 unusual for workstations | Any listening |
| Windows Update | Recent updates should be installed | 30 days |
| Screen Lock | Inactivity timeout should be configured | 900 seconds (15 min) |
| Execution Policy | PowerShell policy shouldn't be Unrestricted/Bypass | RemoteSigned or stricter |
| Network Profile | Should not be connected as Public network | Private/Domain |
| Pending Reboot | No pending reboots from updates | None pending |
_______ _
|__ __| | |
| | ___ ___| |__ __ _ _ __ _ _
| |/ _ \/ __| '_ \ / ` | '__| | | |
| | __/ (__| | | | (_| | | | |_| |
|_|\___|\___|_| |_|\__,_|_| \__, |
__/ |
|___/
Checking system compliance...
COMPLIANT - Device passed all security checks
WARNINGS:
[!] Screen lock timeout not configured or too long (current: 0s, max: 900s)
Fix: Set-ItemProperty -Path 'HKLM:\SOFTWARE\...' -Name 'InactivityTimeoutSecs' -Value 900
ANTIVIRUS:
[+] Windows Defender (Real-time: Enabled, Definitions: Up to date)
.\IsItAllowed.ps1 -OutputFormat JSONReturns structured JSON with all check results, suitable for:
- SIEM ingestion
- Compliance dashboards
- Automated processing
.\IsItAllowed.ps1 -OutputFormat HTML > report.htmlGenerates a styled HTML report suitable for:
- Email distribution
- Compliance documentation
- Management reporting
Create a JSON file to customize policy settings:
{
"MaxUpdateAgeDays": 30,
"ScreenLockMaxSeconds": 900,
"HardFailPorts": [21, 22, 23, 25, 3389],
"WarningPorts": [53, 80, 443],
"RequireBitLocker": true,
"RequireSecureBoot": true,
"RequireSMBv1Disabled": true,
"RequireUAC": true,
"RequireGuestDisabled": true,
"RequireNoAutoLogin": true
}Use with:
.\IsItAllowed.ps1 -ConfigFile .\policy.json| Option | Type | Default | Description |
|---|---|---|---|
MaxUpdateAgeDays |
int | 30 | Days before Windows Update warning |
ScreenLockMaxSeconds |
int | 900 | Maximum screen lock timeout (seconds) |
HardFailPorts |
int[] | [21,22,23,25,3389] | Ports that cause hard failure |
WarningPorts |
int[] | [53,80,443] | Ports that cause warning |
RequireBitLocker |
bool | true | Require BitLocker encryption |
RequireSecureBoot |
bool | true | Require Secure Boot |
RequireSMBv1Disabled |
bool | true | Require SMBv1 disabled |
RequireUAC |
bool | true | Require UAC enabled |
RequireGuestDisabled |
bool | true | Require Guest account disabled |
RequireNoAutoLogin |
bool | true | Require auto-login disabled |
| Code | Meaning | Description |
|---|---|---|
| 0 | Compliant | No hard failures, no warnings |
| 1 | Warnings | No hard failures, but has warnings |
| 2 | Non-compliant | One or more hard failures |
Use in scripts:
.\IsItAllowed.ps1 -Quiet
if ($LASTEXITCODE -eq 2) {
Write-Host "Device is non-compliant!"
}Run daily compliance check and log results:
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -File C:\Scripts\IsItAllowed.ps1 -OutputFormat JSON -Quiet" `
-WorkingDirectory "C:\Scripts"
$trigger = New-ScheduledTaskTrigger -Daily -At "09:00"
Register-ScheduledTask -TaskName "SecurityComplianceCheck" `
-Action $action -Trigger $trigger -Description "Daily security compliance check"- task: PowerShell@2
displayName: 'Security Compliance Check'
inputs:
targetType: 'filePath'
filePath: '$(Build.SourcesDirectory)/IsItAllowed.ps1'
arguments: '-Quiet -OutputFormat JSON'
continueOnError: falseDetection script:
$result = & .\IsItAllowed.ps1 -Quiet -OutputFormat JSON | ConvertFrom-Json
if ($result.IsCompliant) {
Write-Host "Compliant"
exit 0
} else {
Write-Host "Non-compliant: $($result.HardFailures.Count) failures"
exit 1
}$report = .\IsItAllowed.ps1 -OutputFormat JSON -Quiet
$headers = @{
"Authorization" = "Splunk $env:SPLUNK_HEC_TOKEN"
}
$body = @{
event = $report | ConvertFrom-Json
sourcetype = "security:compliance"
} | ConvertTo-Json
Invoke-RestMethod -Uri "https://splunk:8088/services/collector" `
-Method Post -Headers $headers -Body $body| Parameter | Type | Description |
|---|---|---|
-Quiet |
switch | Suppress logo banner |
-OutputFormat |
string | Output format: Console, JSON, HTML |
-ConfigFile |
string | Path to JSON configuration file |
-MaxUpdateAgeDays |
int | Override max days since Windows Update |
-Verbose |
switch | Show detailed progress information |
Some checks require administrator privileges:
- BitLocker status
- SMBv1 feature status
- Some registry keys
Run PowerShell as Administrator for full results.
This occurs when:
- Not running as administrator
- BitLocker feature not installed
- Running on unsupported Windows edition (Home)
This occurs when:
- System uses legacy BIOS instead of UEFI
- Running in a virtual machine without Secure Boot
This occurs when:
- Event log has been cleared
- No updates have ever been installed
- Running on a fresh Windows installation
| Port | Service | Why it's risky |
|---|---|---|
| 21 | FTP | Unencrypted file transfer, credential theft |
| 22 | SSH | Remote shell access, brute force target |
| 23 | Telnet | Unencrypted remote access, credential theft |
| 25 | SMTP | Mail relay abuse, spam source |
| 3389 | RDP | Remote desktop, brute force/BlueKeep |
| Port | Service | Why it's flagged |
|---|---|---|
| 53 | DNS | Workstations shouldn't be DNS servers |
| 80 | HTTP | Workstations shouldn't be web servers |
| 443 | HTTPS | Workstations shouldn't be web servers |
MIT License - See LICENSE file for details.
James Tarran // Techary
- Fork the repository
- Create a feature branch
- Submit a pull request
Issues and feature requests: GitHub Issues