Framework/Listeners/RemoteReports/ControlTelemetry.ps1
Set-StrictMode -Version Latest class ControlTelemetry: ListenerBase { [Microsoft.ApplicationInsights.TelemetryClient] $TelemetryClient; hidden ControlTelemetry() { $this.TelemetryClient = [Microsoft.ApplicationInsights.TelemetryClient]::new() } hidden static [ControlTelemetry] $Instance = $null; static [ControlTelemetry] GetInstance() { if ( $null -eq [ControlTelemetry]::Instance -or $null -eq [ControlTelemetry]::Instance.TelemetryClient) { [ControlTelemetry]::Instance = [ControlTelemetry]::new(); } return [ControlTelemetry]::Instance } [void] RegisterEvents() { $this.UnregisterEvents(); $this.RegisterEvent([AzSdkRootEvent]::GenerateRunIdentifier, { $currentInstance = [ControlTelemetry]::GetInstance(); try { $runIdentifier = [AzSdkRootEventArgument] ($Event.SourceArgs | Select-Object -First 1) $currentInstance.SetRunIdentifier($runIdentifier); } catch { $currentInstance.PublishException($_); } }); $this.RegisterEvent([SVTEvent]::EvaluationCompleted, { if(![RemoteReportHelper]::IsControlTelemetryEnabled()){ return; }; $currentInstance = [ControlTelemetry]::GetInstance(); $currentInstance.TelemetryClient.InstrumentationKey = [RemoteReportHelper]::GetControlTelemetryKey(); try { $invocationContext = [System.Management.Automation.InvocationInfo] $currentInstance.InvocationContext $featureGroup = [RemoteReportHelper]::GetFeatureGroup($invocationContext.MyCommand.Name) $SVTEventContexts = [SVTEventContext[]] $Event.SourceArgs if($featureGroup -eq [FeatureGroup]::Subscription){ [ControlTelemetry]::PushSubscriptionScanResults($currentInstance, $SVTEventContexts) }elseif($featureGroup -eq [FeatureGroup]::Service){ [ControlTelemetry]::PushServiceScanResults($currentInstance, $SVTEventContexts) }else{ } } catch { $currentInstance.PublishException($_); } $currentInstance.TelemetryClient.Flush() }); } static [void] PushSubscriptionScanResults( [ControlTelemetry] $Publisher, ` [SVTEventContext[]] $SVTEventContexts) { $eventData = @{ [TelemetryKeys]::FeatureGroup = [FeatureGroup]::Subscription; "ScanKind" = [RemoteReportHelper]::GetSubscriptionScanKind( $Publisher.InvocationContext.MyCommand.Name, $Publisher.InvocationContext.BoundParameters); } $SVTEventContexts | ForEach-Object { $context = $_ [hashtable] $eventDataClone = $eventData.Clone(); $eventDataClone.Add("ControlIntId", $context.ControlItem.Id); $eventDataClone.Add("ControlId", $context.ControlItem.ControlID); $eventDataClone.Add("ControlSeverity", $context.ControlItem.ControlSeverity); if ($context.ControlItem.Enabled) { $eventDataClone.Add("ActualVerificationResult", $context.ControlResults[0].ActualVerificationResult) $eventDataClone.Add("AttestationStatus", $context.ControlResults[0].AttestationStatus) $eventDataClone.Add("VerificationResult", $context.ControlResults[0].VerificationResult) } else { $eventDataClone.Add("ActualVerificationResult", [VerificationResult]::Disabled) $eventDataClone.Add("AttestationStatus", [AttestationStatus]::None) $eventDataClone.Add("VerificationResult", [VerificationResult]::Disabled) } [ControlTelemetry]::PushEvent($Publisher, $eventDataClone, @{}) } } static [void] PushServiceScanResults( [ControlTelemetry] $Publisher, ` [SVTEventContext[]] $SVTEventContexts) { $NA = "NA" $SVTEventContextFirst = $SVTEventContexts[0] $eventData = @{ [TelemetryKeys]::FeatureGroup = [FeatureGroup]::Service; "ScanKind" = [RemoteReportHelper]::GetServiceScanKind( $Publisher.InvocationContext.MyCommand.Name, $Publisher.InvocationContext.BoundParameters); "Feature" = $SVTEventContextFirst.FeatureName; "ResourceGroup" = $SVTEventContextFirst.ResourceContext.ResourceGroupName; "ResourceName" = $SVTEventContextFirst.ResourceContext.ResourceName; "ResourceId" = $SVTEventContextFirst.ResourceContext.ResourceId; } $SVTEventContexts | ForEach-Object { $SVTEventContext = $_ [hashtable] $eventDataClone = $eventData.Clone() $eventDataClone.Add("ControlIntId", $SVTEventContext.ControlItem.Id); $eventDataClone.Add("ControlId", $SVTEventContext.ControlItem.ControlID); $eventDataClone.Add("ControlSeverity", $SVTEventContext.ControlItem.ControlSeverity); if (!$SVTEventContext.ControlItem.Enabled) { $eventDataClone.Add("VerificationResult", [VerificationResult]::Disabled) $eventDataClone.Add("AttestationStatus", [AttestationStatus]::None) $eventDataClone.Add("VerificationResult", [VerificationResult]::Disabled) [ControlTelemetry]::PushEvent($Publisher, $eventDataClone, @{}) } elseif ($SVTEventContext.ControlResults.Count -eq 1 -and ` ($SVTEventContextFirst.ResourceContext.ResourceName -eq $SVTEventContext.ControlResults[0].ChildResourceName -or ` [string]::IsNullOrWhiteSpace($SVTEventContext.ControlResults[0].ChildResourceName))) { $eventDataClone.Add("ActualVerificationResult", $SVTEventContext.ControlResults[0].ActualVerificationResult) $eventDataClone.Add("AttestationStatus", $SVTEventContext.ControlResults[0].AttestationStatus) $eventDataClone.Add("VerificationResult", $SVTEventContext.ControlResults[0].VerificationResult) $eventDataClone.Add("IsNestedResource", 'No') $eventDataClone.Add("NestedResourceName", $NA) [ControlTelemetry]::PushEvent($Publisher, $eventDataClone, @{}) } elseif ($SVTEventContext.ControlResults.Count -eq 1 -and ` $SVTEventContextFirst.ResourceContext.ResourceName -ne $SVTEventContext.ControlResults[0].ChildResourceName) { $eventDataClone.Add("ActualVerificationResult", $SVTEventContext.ControlResults[0].ActualVerificationResult) $eventDataClone.Add("AttestationStatus", $SVTEventContext.ControlResults[0].AttestationStatus) $eventDataClone.Add("VerificationResult", $SVTEventContext.ControlResults[0].VerificationResult) $eventDataClone.Add("IsNestedResource", 'Yes') $eventDataClone.Add("NestedResourceName", $SVTEventContext.ControlResults[0].ChildResourceName) [ControlTelemetry]::PushEvent($Publisher, $eventDataClone, @{}) } elseif ($SVTEventContext.ControlResults.Count -gt 1) { $eventDataClone.Add("IsNestedResource", 'Yes') $SVTEventContext.ControlResults | Foreach-Object { [hashtable] $eventDataCloneL2 = $eventDataClone.Clone() $eventDataCloneL2.Add("ActualVerificationResult", $_.ActualVerificationResult) $eventDataCloneL2.Add("AttestationStatus", $_.AttestationStatus) $eventDataCloneL2.Add("VerificationResult", $_.VerificationResult) $eventDataCloneL2.Add("NestedResourceName", $_.ChildResourceName) [ControlTelemetry]::PushEvent($Publisher, $eventDataCloneL2, @{}) } } } } static [void] PushEvent([ControlTelemetry] $Publisher, ` [hashtable] $Properties, [hashtable] $Metrics) { try{ [ControlTelemetry]::SetCommonProperties($Publisher, $Properties); $event = [Microsoft.ApplicationInsights.DataContracts.EventTelemetry]::new() $event.Name = "Control Scanned" $Properties.Keys | ForEach-Object { try{ $event.Properties.Add($_, $Properties[$_].ToString()); } catch{ } } $Metrics.Keys | ForEach-Object { try{ $event.Metrics.Add($_, $Metrics[$_]); } catch{ } } $Publisher.TelemetryClient.TrackEvent($event); } catch{ } } hidden static [void] SetCommonProperties([ControlTelemetry] $Publisher, [hashtable] $Properties) { try{ $NA = "NA"; $Properties.Add("InfoVersion", "V1"); try{ $Properties.Add("ScanSource", [RemoteReportHelper]::GetScanSource()); }catch{} try{ $Properties.Add("ScannerVersion", $Publisher.GetCurrentModuleVersion()); }catch{} try{ $Properties.Add("ControlVersion", $Publisher.GetCurrentModuleVersion()); }catch{} try{ $azureContext = Get-AzureRmContext try{ $Properties.Add([TelemetryKeys]::SubscriptionId, $azureContext.Subscription.Id) }catch{} try{ $Properties.Add([TelemetryKeys]::SubscriptionName, $azureContext.Subscription.Name) }catch{} try{ $Properties.Add("AzureEnv", $azureContext.Environment.Name) }catch{} try{ $Properties.Add("TenantId", $azureContext.Tenant.Id) }catch{} try{ $Properties.Add("AccountId", $azureContext.Account.Id) }catch{} try{ $Properties.Add("RunIdentifier", [RemoteReportHelper]::Mask($azureContext.Account.Id + '##' + $Publisher.RunIdentifier)); }catch{ $Properties.Add("RunIdentifier", $Publisher.RunIdentifier); } try{ $Properties.Add("AccountType", $azureContext.Account.Type) }catch{} }catch{ } } catch{ } } } |