#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'"
}