[CmdletBinding()] param() Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' function Invoke-DlpPolicyGetJson { param( [Parameter(Mandatory = $true)][string]$Uri, [int]$TimeoutSec = 10 ) $request = [System.Net.HttpWebRequest]::Create($Uri) $request.Method = 'GET' $request.Accept = 'application/json' $request.KeepAlive = $false $request.Timeout = $TimeoutSec * 1000 $request.ReadWriteTimeout = $TimeoutSec * 1000 $response = $request.GetResponse() try { $stream = $response.GetResponseStream() $reader = New-Object System.IO.StreamReader($stream, [System.Text.Encoding]::UTF8) try { $reader.ReadToEnd() | ConvertFrom-Json } finally { $reader.Close() } } finally { $response.Close() } } function Invoke-DlpPolicyPostJson { param( [Parameter(Mandatory = $true)][string]$Uri, [Parameter(Mandatory = $true)]$Body, [int]$TimeoutSec = 10 ) $json = $Body | ConvertTo-Json -Depth 10 -Compress $bytes = [System.Text.Encoding]::UTF8.GetBytes($json) $request = [System.Net.HttpWebRequest]::Create($Uri) $request.Method = 'POST' $request.Accept = 'application/json' $request.ContentType = 'application/json' $request.KeepAlive = $false $request.Timeout = $TimeoutSec * 1000 $request.ReadWriteTimeout = $TimeoutSec * 1000 $request.ContentLength = $bytes.Length $stream = $request.GetRequestStream() try { $stream.Write($bytes, 0, $bytes.Length) } finally { $stream.Close() } $response = $request.GetResponse() try { $reader = New-Object System.IO.StreamReader($response.GetResponseStream(), [System.Text.Encoding]::UTF8) try { $raw = $reader.ReadToEnd() if ($raw) { return ($raw | ConvertFrom-Json) } return $null } finally { $reader.Close() } } finally { $response.Close() } } function Get-RemoteDlpPolicyBundle { param( [Parameter(Mandatory = $true)][string]$ApiBase, [int]$TimeoutSec = 10 ) $bundle = Invoke-DlpPolicyGetJson -Uri ($ApiBase.TrimEnd('/') + '/dlp/policies/active') -TimeoutSec $TimeoutSec if (-not $bundle) { throw 'Policy engine returned empty response.' } if (-not $bundle.active) { throw 'Policy engine has no active policy.' } if (-not $bundle.policy) { throw 'Policy engine response has no policy payload.' } return $bundle } function Get-RemoteDlpPolicyDesired { param( [Parameter(Mandatory = $true)][string]$ApiBase, [Parameter(Mandatory = $true)][string]$AgentId, [int]$TimeoutSec = 10 ) $path = '/dlp/policies/agents/{0}/desired' -f [uri]::EscapeDataString($AgentId) return Invoke-DlpPolicyGetJson -Uri ($ApiBase.TrimEnd('/') + $path) -TimeoutSec $TimeoutSec } function Send-DlpPolicyAgentHeartbeat { param( [Parameter(Mandatory = $true)][string]$ApiBase, [Parameter(Mandatory = $true)][string]$AgentId, [string]$Hostname, [string]$Version, [string]$Checksum, [int]$TimeoutSec = 10 ) $path = '/dlp/policies/agents/{0}/heartbeat' -f [uri]::EscapeDataString($AgentId) $body = @{ hostname = $Hostname version = $Version checksum = $Checksum updatedAtUtc = (Get-Date).ToUniversalTime().ToString('o') } return Invoke-DlpPolicyPostJson -Uri ($ApiBase.TrimEnd('/') + $path) -Body $body -TimeoutSec $TimeoutSec } function Read-CachedDlpPolicyBundle { param([Parameter(Mandatory = $true)][string]$CachePath) if (-not (Test-Path -LiteralPath $CachePath)) { return $null } try { return Get-Content -LiteralPath $CachePath -Raw | ConvertFrom-Json } catch { return $null } } function Save-CachedDlpPolicyBundle { param( [Parameter(Mandatory = $true)]$Bundle, [Parameter(Mandatory = $true)][string]$CachePath ) $directory = Split-Path -Path $CachePath -Parent if ($directory -and -not (Test-Path -LiteralPath $directory)) { New-Item -Path $directory -ItemType Directory -Force | Out-Null } $json = $Bundle | ConvertTo-Json -Depth 20 Set-Content -LiteralPath $CachePath -Value $json -Encoding UTF8 } if ($ExecutionContext.SessionState.Module) { Export-ModuleMember -Function Invoke-DlpPolicyGetJson, Get-RemoteDlpPolicyBundle, Get-RemoteDlpPolicyDesired, Send-DlpPolicyAgentHeartbeat, Read-CachedDlpPolicyBundle, Save-CachedDlpPolicyBundle }