[CmdletBinding(SupportsShouldProcess)] param() $ErrorActionPreference = 'Stop' function Get-LocalGroupMemberSid { param([Parameter(Mandatory)][string]$Name) $group = [ADSI]("WinNT://$env:COMPUTERNAME/$Name,group") foreach ($member in @($group.psbase.Invoke('Members'))) { try { $sidBytes = $member.GetType().InvokeMember('objectSid', [Reflection.BindingFlags]::GetProperty, $null, $member, $null) if ($sidBytes) { ([Security.Principal.SecurityIdentifier]::new([byte[]]$sidBytes, 0)).Value } } catch { } } } $identity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = [Security.Principal.WindowsPrincipal]::new($identity) if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { throw 'Run this script from an elevated Windows PowerShell session.' } # Use invariant audit subcategory GUIDs so this works on English and Spanish # installations. Logon, logoff, and other logon/logoff events provide the # session identifiers required to correlate usage centrally. $auditSubcategories = @( '{0CCE9215-69AE-11D9-BED3-505054503030}', # Logon '{0CCE9216-69AE-11D9-BED3-505054503030}', # Logoff '{0CCE921C-69AE-11D9-BED3-505054503030}' # Other Logon/Logoff Events ) if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Enable SGU session auditing and event forwarding prerequisites')) { foreach ($subcategory in $auditSubcategories) { & auditpol.exe /set "/subcategory:$subcategory" /success:enable /failure:enable | Out-Null if ($LASTEXITCODE -ne 0) { throw "auditpol failed for subcategory $subcategory with exit code $LASTEXITCODE." } } # Security events are read by the Windows Event Forwarding plug-in under # NETWORK SERVICE. Resolve both principals by SID for localized Windows. $eventLogReadersSid = [Security.Principal.SecurityIdentifier]::new('S-1-5-32-573') $networkServiceSid = [Security.Principal.SecurityIdentifier]::new('S-1-5-20') $eventLogReadersGroup = ($eventLogReadersSid.Translate( [Security.Principal.NTAccount]).Value -split '\\', 2)[1] $members = @(Get-LocalGroupMemberSid -Name $eventLogReadersGroup) $eventLogReaderMembershipChanged = $false if ($members -notcontains $networkServiceSid.Value) { Add-LocalGroupMember -SID $eventLogReadersSid -Member $networkServiceSid.Value $eventLogReaderMembershipChanged = $true } Set-Service WinRM -StartupType Automatic if ((Get-Service WinRM).Status -ne 'Running') { Start-Service WinRM } elseif ($eventLogReaderMembershipChanged) { Restart-Service WinRM -Force } & wevtutil.exe set-log Security /maxsize:268435456 /retention:false /autobackup:false if ($LASTEXITCODE -ne 0) { throw "wevtutil failed to configure the local Security log with exit code $LASTEXITCODE." } } [pscustomobject]@{ ComputerName = $env:COMPUTERNAME WinRM = (Get-Service WinRM).Status.ToString() SecurityLogMaximumBytes = (Get-WinEvent -ListLog Security).MaximumSizeInBytes AuditSubcategories = $auditSubcategories EventForwardingPolicy = Test-Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\EventLog\EventForwarding\SubscriptionManager' }