#Requires -Version 5.1 [CmdletBinding(SupportsShouldProcess)] param( [string]$CollectorFqdn = "$env:COMPUTERNAME.$env:USERDNSDOMAIN", [string]$ComputerOuDn = 'OU=Laboratorio,DC=lci,DC=lasalle,DC=mx', [string]$MonitoringRoot = 'C:\ProgramData\SGU\Monitoring', [ValidateRange(30, 730)] [int]$RetentionDays = 183 ) $ErrorActionPreference = 'Stop' $subscriptionId = 'SGU-Lab-Monitoring' $maintenanceScriptName = 'Invoke-SguMonitoringMaintenance.ps1' $reportScriptName = 'Get-SguUsageReport.ps1' $brokerReportScriptName = 'Get-SguBrokerLog.ps1' $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 on the domain event collector.' } Import-Module ActiveDirectory -ErrorAction Stop Get-ADOrganizationalUnit -Identity $ComputerOuDn -ErrorAction Stop | Out-Null foreach ($requiredScript in $maintenanceScriptName,$reportScriptName,$brokerReportScriptName) { if (-not (Test-Path -LiteralPath (Join-Path $PSScriptRoot $requiredScript) -PathType Leaf)) { throw "$requiredScript must be beside Install-SguDomainMonitoring.ps1." } } if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME, 'Install the SGU domain monitoring collector')) { Set-Service EventLog -StartupType Automatic if ((Get-Service EventLog).Status -ne 'Running') { Start-Service EventLog } & wecutil.exe quick-config /quiet if ($LASTEXITCODE -ne 0) { throw "wecutil quick-config failed with exit code $LASTEXITCODE." } Set-Service Wecsvc -StartupType Automatic Start-Service Wecsvc & wevtutil.exe set-log ForwardedEvents /enabled:true /maxsize:536870912 /retention:false /autobackup:false if ($LASTEXITCODE -ne 0) { throw "wevtutil failed to configure ForwardedEvents with exit code $LASTEXITCODE." } $query = @' '@ $escapedQuery = [Security.SecurityElement]::Escape($query) $subscriptionXml = @" $subscriptionId SourceInitiated SGU interactive sessions, failures, reconnects, and workstation power state. true http://schemas.microsoft.com/wbem/wsman/1/windows/EventLog Custom 530000 $escapedQuery false HTTP Events ForwardedEvents O:NSG:NSD:(A;;GA;;;DC)(A;;GA;;;NS) "@ New-Item -ItemType Directory -Path $MonitoringRoot -Force | Out-Null $subscriptionPath = Join-Path $MonitoringRoot 'SGU-Lab-Monitoring.xml' [IO.File]::WriteAllText($subscriptionPath, $subscriptionXml, [Text.UTF8Encoding]::new($true)) $existingSubscriptions = @(& wecutil.exe enum-subscription 2>$null) if ($existingSubscriptions -contains $subscriptionId) { & wecutil.exe delete-subscription $subscriptionId if ($LASTEXITCODE -ne 0) { throw "Could not replace the existing $subscriptionId subscription." } } & wecutil.exe create-subscription $subscriptionPath if ($LASTEXITCODE -ne 0) { throw "Could not create the $subscriptionId subscription." } foreach ($scriptName in $maintenanceScriptName,$reportScriptName,$brokerReportScriptName) { Copy-Item -LiteralPath (Join-Path $PSScriptRoot $scriptName) ` -Destination (Join-Path $MonitoringRoot $scriptName) -Force } $configuration = [ordered]@{ CollectorFqdn = $CollectorFqdn ComputerOuDn = $ComputerOuDn RetentionDays = $RetentionDays SubscriptionId = $subscriptionId } [IO.File]::WriteAllText( (Join-Path $MonitoringRoot 'monitoring.json'), ($configuration | ConvertTo-Json), [Text.UTF8Encoding]::new($false)) $powerShell = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" $maintenanceScript = Join-Path $MonitoringRoot $maintenanceScriptName $inventoryAction = New-ScheduledTaskAction -Execute $powerShell -Argument ( "-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File `"$maintenanceScript`" " + "-MonitoringRoot `"$MonitoringRoot`" -ComputerOuDn `"$ComputerOuDn`" -RetentionDays $RetentionDays -InventoryOnly") $inventoryTrigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) ` -RepetitionInterval (New-TimeSpan -Minutes 5) ` -RepetitionDuration (New-TimeSpan -Days 3650) $taskSettings = New-ScheduledTaskSettingsSet -StartWhenAvailable ` -ExecutionTimeLimit (New-TimeSpan -Minutes 10) -RestartCount 2 ` -RestartInterval (New-TimeSpan -Minutes 1) Register-ScheduledTask -TaskName 'SGU-Monitoring-Inventory' -Action $inventoryAction ` -Trigger $inventoryTrigger -Settings $taskSettings -User 'SYSTEM' -RunLevel Highest -Force | Out-Null $retentionAction = New-ScheduledTaskAction -Execute $powerShell -Argument ( "-NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File `"$maintenanceScript`" " + "-MonitoringRoot `"$MonitoringRoot`" -ComputerOuDn `"$ComputerOuDn`" -RetentionDays $RetentionDays") $retentionTrigger = New-ScheduledTaskTrigger -Daily -At '12:10 AM' Register-ScheduledTask -TaskName 'SGU-Monitoring-Retention' -Action $retentionAction ` -Trigger $retentionTrigger -Settings $taskSettings -User 'SYSTEM' -RunLevel Highest -Force | Out-Null & $maintenanceScript -MonitoringRoot $MonitoringRoot -ComputerOuDn $ComputerOuDn ` -RetentionDays $RetentionDays -InventoryOnly | Out-Null } [pscustomobject]@{ Collector = $CollectorFqdn CollectorService = (Get-Service Wecsvc).Status.ToString() SubscriptionId = $subscriptionId SubscriptionEnabled = @(& wecutil.exe enum-subscription) -contains $subscriptionId RetentionDays = $RetentionDays InventoryTask = (Get-ScheduledTask -TaskName 'SGU-Monitoring-Inventory').State RetentionTask = (Get-ScheduledTask -TaskName 'SGU-Monitoring-Retention').State MachineStatusPath = Join-Path $MonitoringRoot 'Reports\machine-status.json' UsageReportCommand = "& '$MonitoringRoot\$reportScriptName'" BrokerLogCommand = "& '$MonitoringRoot\$brokerReportScriptName'" }