functions/Set-WELCEventChannel.ps1
function Set-WELCEventChannel { <# .SYNOPSIS Set-WELCEventChannel .DESCRIPTION Set various properties on a EventChannel .PARAMETER ChannelConfig InputObject (WELC.ChannelConfig) from Excel Template file Can be created by Import-WELCChannelDefinition -Path ".\MyTemplate.xls" -OutputChannelConfig .PARAMETER EventChannel InputObject from Get-WELCEventChannel Available Alias on the parameter: EventLogChannel .PARAMETER ChannelFullName The name of the channel to be set .PARAMETER ComputerName The computer where to set the configuration .PARAMETER Enabled The status of the logfile. By default the logfiles are enabled after execution .PARAMETER LogMode Specifies how events in the EventChannel are treated, if the EventChannel reaches the maximum. Possilibilites: "AutoBackup" = File from EventChannel will be renamed and a newly file will be created "Circular" = Oldest event will be overwritten "Retain" = Newly events will be refused .PARAMETER LogFilePath The path in the filesystem for the EventChannel EVTX file This can be a full qualified filename - if only ONE EventChannel is to be set/ piped in. Effectivly this means a rename of the file for the EventChannel. If multiple configurations should be set/ piped in, the value on this parameter should be a FOLDER, not a file! .PARAMETER CompressLogFolder Specifies if the folder with the log files get compressed .PARAMETER MaxEventLogSize The maximum size in bytes for the EventChannel .PARAMETER AllowFileAccessForLocalService The WellKnownPrincipal 'Local Service' will add in the NTFS ACL to gain access to the logfile If the channel is planned to be used in "Windows Event Forwarding" this should probably set to true .PARAMETER EventChannelSDDL SDDL string to set access on the eventlog within the WinodwsEventLog system itself This access object controls who can view events in the EventLog for this channel So it's not on the filesystem, it's in MMC, WMI or PowerShell .PARAMETER PassThru The moved files will be parsed to the pipeline for further processing. .PARAMETER WhatIf If this switch is enabled, no actions are performed but informational messages will be displayed that explain what would happen if the command were to run. .PARAMETER Confirm If this switch is enabled, you will be prompted for confirmation before executing any operations that change state. .NOTES Author: Andreas Bellstedt This a is quite far modified version from Project Sauron fork. Name: Prep-EventChannels.ps1 Version: 1.1 Author: Russell Tomkins - Microsoft Premier Field Engineer Blog: https://aka.ms/russellt Preparation of event channels to receive event collection subscriptions from an input CSV Source: https://www.github.com/russelltomkins/ProjectSauron Refer to this blog series for more details http://blogs.technet.microsoft.com/russellt/2017/03/23/project-sauron-part-1 .LINK https://github.com/AndiBellstedt/WinEventLogCustomization .EXAMPLE PS C:\> Set-WELCEventChannel -ChannelFullName "App1/MyLog" -LogMode Circular -LogFilePath "C:\EventLogs\App1-MyLog.evtx" Set the 'MyLog' EventLog in the EventFolder 'App1' to circular logging and the path of the logfile to 'C:\EventLogs\App1-MyLog.evtx' .EXAMPLE PS C:\> $channels | Set-WELCEventChannel -Enabled $true -MaxEventLogSize 1GB Enables the EventChannels from the $channels variable and set maximum size to 1GB. Assuming the $channels variable is filled with something like $channels = Get-WELCEventChannel -ChannelFullName "App1/MyLog", "App2/MyLog" .EXAMPLE PS C:\> $ChannelConfig | Set-WELCEventChannel -Enabled $true -CompressLogFolder $true -AllowFileAccessForLocalService $true Enables the EventChannels from the $ChannelConfig variable and set all the properties within the $ChannelConfig variable. Additionally, the logfile/logfolder for the EventLogs will be compressed (except if it is a folder in Windows\System32), and the SID for "Local Service" gain Read/Write-Access. Assuming the $channels variable is filled with something like $ChannelConfig = Import-WELCChannelDefinition -Path C:\EventLogs\WinEventLogCustomization.xlsx -OutputChannelConfig Excel template file can be created/opened with Open-WELCExcelTemplate #> [CmdletBinding( DefaultParameterSetName = "ChannelName", SupportsShouldProcess = $true, PositionalBinding = $true, ConfirmImpact = 'Medium' )] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSReviewUnusedParameter", '', Justification = "Intentional, Pester not covering the usage correct")] Param( [Parameter( ParameterSetName = "TemplateChannelConfig", Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0 )] [ValidateNotNullOrEmpty()] [WELC.ChannelConfig[]] $ChannelConfig, [Parameter( ParameterSetName = "EventChannel", Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0 )] [Alias("EventLogChannel")] [WELC.EventLogChannel[]] $EventChannel, [Parameter( ParameterSetName = "ChannelName", Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0 )] [Alias("ChannelName")] [String[]] $ChannelFullName, [Parameter( ParameterSetName = "TemplateChannelConfig", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 1 )] [Parameter( ParameterSetName = "ChannelName", ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 1 )] [Alias("Host", "Hostname", "Computer", "DNSHostName")] [PSFComputer[]] $ComputerName = $env:COMPUTERNAME, [Parameter(ParameterSetName = "EventChannel")] [Parameter(ParameterSetName = "ChannelName")] [bool] $Enabled, [Parameter(ParameterSetName = "EventChannel")] [Parameter(ParameterSetName = "ChannelName")] [int] $MaxEventLogSize, [Parameter(ParameterSetName = "EventChannel")] [Parameter(ParameterSetName = "ChannelName")] [ValidateSet("AutoBackup", "Circular", "Retain")] [string] $LogMode, [Parameter(ParameterSetName = "EventChannel")] [Parameter(ParameterSetName = "ChannelName")] [String] $LogFilePath, [Parameter(ParameterSetName = "EventChannel")] [Parameter(ParameterSetName = "ChannelName")] [Alias("Compress")] [bool] $CompressLogFolder, [bool] $AllowFileAccessForLocalService, [String] $EventChannelSDDL, [switch] $PassThru ) Begin { $channelFullNameBound = Test-PSFParameterBinding -ParameterName ChannelFullName $computerBound = Test-PSFParameterBinding -ParameterName ComputerName^ $configList = New-Object System.Collections.ArrayList # validation on parameter LogFilePath if ($LogFilePath) { $LogFilePath = $LogFilePath.TrimEnd("\") if ($LogFilePath -like '%SystemRoot%*') { $LogFilePath = $LogFilePath.Replace('%SystemRoot%', $env:SystemRoot) } if ($LogFilePath.EndsWith(".evtx")) { $logFileFolder = Split-Path -Path $LogFilePath $logFileFullName = $LogFilePath } else { $logFileFolder = $LogFilePath $logFileFullName = "ToBeCalculated" } } # if compression is set and windows-folder is specified as LogFilePath -> abort, to avoid 'unhealthy' system modification if ($LogFilePath -like "$($env:SystemRoot)\System32\*" -and $CompressLogFolder -eq $true) { Stop-PSFFunction -Message "Hardcoded exception, not going to set compression within windows-System32-folder. Aborting function" -EnableException $true break } } Process { #region parameterset workarround Write-PSFMessage -Level Debug -Message "ParameterNameSet: $($PsCmdlet.ParameterSetName)" #ToDo: Check if this behaves right. What is if ComputerName "foo" is piped in and Channelfullname is specified, and vice versa # Workarround parameter binding behaviour of powershell in combination with ComputerName Piping if (-not ($channelFullNameBound -or $computerBound) -and $ComputerName.InputObject) { if ($ComputerName.InputObject -is [string]) { $ComputerName = $env:ComputerName } else { $ChannelFullName = "" } } #endregion parameterset workarround switch ($pscmdlet.ParameterSetName) { "TemplateChannelConfig" { Write-PSFMessage -Level Verbose -Message "Gathering $(([array]$ChannelConfig).count) channel configurations" foreach ($channelConfigItem in $ChannelConfig) { foreach ($computer in $ComputerName) { $eventChannel = $null $eventChannel = Get-WELCEventChannel -ChannelFullName $channelConfigItem.ChannelName -ComputerName $computer -ErrorAction SilentlyContinue if ($eventChannel) { foreach ($eventChannelItem in $eventChannel) { Write-PSFMessage -Level Debug -Message "Collecting config object for '$($eventChannelItem.Name)' on '$($computer)'" $null = $configList.Add( [PSCustomObject]@{ EventChannel = $eventChannelItem Enabled = $channelConfigItem.Enabled MaxEventLogSize = $channelConfigItem.MaxEventLogSize LogMode = $channelConfigItem.LogMode LogFileFullName = $channelConfigItem.LogFullName LogFilePath = (Split-Path -Path $channelConfigItem.LogFullName) CompressLogFolder = $CompressLogFolder AllowFileAccessForLocalService = $AllowFileAccessForLocalService EventChannelSDDL = $EventChannelSDDL } ) } } else { Write-PSFMessage -Level Warning -Message "Skipping '$($channelConfigItem.ChannelName)' on '$($computer)'" continue } } } } "EventChannel" { foreach ($eventChannelItem in $EventChannel) { Write-PSFMessage -Level Debug -Message "Collecting config object for '$($eventChannelItem.ChannelFullName)' on '$($eventChannelItem.ComputerName)'" $null = $configList.Add( [PSCustomObject]@{ EventChannel = $eventChannelItem Enabled = ( if (Test-PSFParameterBinding -ParameterName Enabled) { $Enabled } ) MaxEventLogSize = ( if (Test-PSFParameterBinding -ParameterName MaxEventLogSize) { $MaxEventLogSize } ) LogMode = ( if (Test-PSFParameterBinding -ParameterName LogMode) { $LogMode } ) LogFileFullName = ( if ($logFileFullName -like "ToBeCalculated") { "$($logFileFolder)\$($eventChannelItem.LogFile)" } elseif (Test-PSFParameterBinding -ParameterName LogFilePath) { $logFileFullName } ) LogFilePath = ( if (Test-PSFParameterBinding -ParameterName LogFilePath) { $logFileFolder } ) CompressLogFolder = ( if (Test-PSFParameterBinding -ParameterName CompressLogFolder) { $CompressLogFolder } ) AllowFileAccessForLocalService = ( if (Test-PSFParameterBinding -ParameterName AllowFileAccessForLocalService) { $AllowFileAccessForLocalService } ) EventChannelSDDL = ( if (Test-PSFParameterBinding -ParameterName EventChannelSDDL) { $EventChannelSDDL } ) } ) } } "ChannelName" { foreach ($channelNameItem in $ChannelFullName) { foreach ($computer in $ComputerName) { $eventChannel = $null $eventChannel = Get-WELCEventChannel -ChannelFullName $channelNameItem -ComputerName $computer -ErrorAction SilentlyContinue if ($eventChannel) { foreach ($eventChannelItem in $eventChannel) { Write-PSFMessage -Level Debug -Message "Collecting config object for '$($eventChannelItem.Name)' on '$($computer)'" $null = $configList.Add( [PSCustomObject]@{ EventChannel = $eventChannelItem Enabled = ( if (Test-PSFParameterBinding -ParameterName Enabled) { $Enabled } ) MaxEventLogSize = ( if (Test-PSFParameterBinding -ParameterName MaxEventLogSize) { $MaxEventLogSize } ) LogMode = ( if (Test-PSFParameterBinding -ParameterName LogMode) { $LogMode } ) LogFileFullName = ( if ($logFileFullName -like "ToBeCalculated") { "$($logFileFolder)\$($eventChannelItem.LogFile)" } elseif (Test-PSFParameterBinding -ParameterName LogFilePath) { $logFileFullName } ) LogFilePath = ( if (Test-PSFParameterBinding -ParameterName LogFilePath) { $logFileFolder } ) CompressLogFolder = ( if (Test-PSFParameterBinding -ParameterName CompressLogFolder) { $CompressLogFolder } ) AllowFileAccessForLocalService = ( if (Test-PSFParameterBinding -ParameterName AllowFileAccessForLocalService) { $AllowFileAccessForLocalService } ) EventChannelSDDL = ( if (Test-PSFParameterBinding -ParameterName EventChannelSDDL) { $EventChannelSDDL } ) } ) } } else { Write-PSFMessage -Level Warning -Message "Skipping '$($channelNameItem)' on '$($computer)'" continue } } } } Default { Stop-PSFFunction -Message "Unhandeled ParameterSetName. Developers mistake." -EnableException $true throw } } } End { # invalid configuration attempt - Parameter 'LogFilePath' specified as file and multiple channels should be configured if ($pscmdlet.ParameterSetName -notlike "TemplateChannelConfig" -and $LogFilePath -and $logFileFullName -notlike "ToBeCalculated" -and $configList.count -gt 1) { Stop-PSFFunction -Message "Parameter 'LogFilePath' was specified as a file, but more than one EventChannels where specified/piped. This leads to unvalid configuration. Each EventChannel has to have it's own LogFile. Please specify a folder on parameter 'LogFilePath'. Aborting..." -EnableException $true throw } Write-PSFMessage -Level Verbose -Message "Working trough list of $($configList.Count) collected EventChannel$(if($configList.Count -gt 1){"s"}) to configure" foreach ($configItem in $configList) { Write-PSFMessage -Level Verbose -Message "Processing '$($configItem.EventChannel.Name)' on '$($configItem.EventChannel.PSComputerName)'" # Get current folder for EventLogFile $eventLogFolderCurrent = Invoke-PSFCommand -ComputerName $configItem.EventChannel.PSComputerName -ArgumentList $configItem.EventChannel.LogFolder -ScriptBlock { $_query = "select * from CIM_Directory where name = `"$($args[0].Replace('\','\\'))`"" Get-CimInstance -Query $_query -ErrorAction SilentlyContinue -Verbose:$false -Debug:$false } # Check if FilePath for EventChannel should be modified if ($configItem.LogFilePath -and ($eventLogFolderCurrent.Name -notlike $configItem.LogFilePath)) { Write-PSFMessage -Level Verbose -Message "Set new path '$($configItem.LogFilePath)' for EventChannel" # First, check if destination folder is already present Write-PSFMessage -Level Debug -Message "Test new path: $($configItem.LogFilePath)" $destinationFolder = Invoke-PSFCommand -ComputerName $configItem.EventChannel.PSComputerName -ArgumentList $configItem.LogFilePath -ErrorVariable invokeErrors -ScriptBlock { $_query = "select * from CIM_Directory where name = `"$($args[0].Replace('\','\\'))`"" $_result = Get-CimInstance -Query $_query -ErrorAction Ignore -Verbose:$false -Debug:$false # if folder is not present, try to query root folder, to check if drive is valid if (-not $_result) { $null = Get-Item -Path "$($args[0].split("\")[0])\" -ErrorAction SilentlyContinue } else { $_result } } # if error occured = drive is not present/valid if ($invokeErrors.Exception) { Write-PSFMessage -Level Error -Message "Invalid path '$($configItem.LogFilePath)' on system '$($configItem.EventChannel.PSComputerName)'! Possibly inaccessable drive/volume" -EnableException $true -Exception $invokeErrors.Exception -ErrorRecord $invokeErrors -Target $configItem.EventChannel.PSComputerName continue } Remove-Variable -Name invokeErrors -Force -Confirm:$false -WhatIf:$false -Verbose:$false -Debug:$false -ErrorAction Ignore # if folder is not available, create it If (-not $destinationFolder) { if ($pscmdlet.ShouldProcess("EventChannel '$($configItem.EventChannel.Name)' on computer '$($configItem.EventChannel.PSComputerName)'", "Create folder '$($configItem.LogFilePath)'")) { Write-PSFMessage -Level Verbose -Message "Create folder '$($configItem.LogFilePath)' for EventChannel" try { $destinationFolder = Invoke-PSFCommand -ComputerName $configItem.EventChannel.PSComputerName -ArgumentList $configItem.LogFilePath -ErrorAction Stop -ErrorVariable invokeErrors -ScriptBlock { $_folder = New-Item -Type Directory -Path $args[0] -Force -ErrorAction Stop $_query = "select * from CIM_Directory where name = `"$($_folder.FullName.Replace('\','\\'))`"" Get-CimInstance -Query $_query -ErrorAction SilentlyContinue -Verbose:$false -Debug:$false } } catch { Write-PSFMessage -Level Error -Message "Unable to create folder '$($configItem.LogFilePath)' on '$($configItem.EventChannel.PSComputerName)'" -EnableException $true -Exception $_.Exception -ErrorRecord $_ -Target $configItem.EventChannel.PSComputerName continue } } } # Set new folder to EventChannel if ($pscmdlet.ShouldProcess("EventChannel '$($configItem.EventChannel.Name)' on computer '$($configItem.EventChannel.PSComputerName)'", "Set new destination '$($configItem.LogFileFullName)'")) { Write-PSFMessage -Level Verbose -Message "Set new destination '$($configItem.LogFileFullName)' for EventChannel '$($configItem.EventChannel.Name)' on computer '$($configItem.EventChannel.PSComputerName)'" $invokeParam = @{ "ComputerName" = $configItem.EventChannel.PSComputerName "ArgumentList" = ($configItem.EventChannel.Name , $configItem.LogFileFullName) "ErrorAction" = "Stop" "ErrorVariable" = "invokeErrors" } try { Invoke-PSFCommand @invokeParam -ScriptBlock { $_eventChannelName = $args[0] $_logFileFullName = $args[1] $_channel = Get-WinEvent -ListLog $_eventChannelName -Force -ErrorAction Stop $error.Clear() # backup current status $_currentIsEnabled = $_channel.IsEnabled # Disable to change settings $_channel.IsEnabled = $false $_channel.SaveChanges() # Set path on channel $_channel.LogFilePath = $_logFileFullName $_channel.IsEnabled = $_currentIsEnabled $_channel.SaveChanges() if ($error.Exception) { Write-Error "" -ErrorAction Stop } } } catch { Write-PSFMessage -Level Error -Message "Unable to set new destination '$($configItem.LogFileFullName)' on '$($configItem.EventChannel.PSComputerName)'" -EnableException $true -Exception $_.Exception -ErrorRecord $_ -Target $configItem.EventChannel.PSComputerName } } } else { $destinationFolder = $eventLogFolderCurrent } Remove-Variable -Name invokeErrors -Force -Confirm:$false -WhatIf:$false -Verbose:$false -Debug:$false -ErrorAction Ignore # Add an ACE to allow LOCAL SERVICE to modify the folder if ($configItem.AllowFileAccessForLocalService) { if ($pscmdlet.ShouldProcess("EventChannel '$($configItem.EventChannel.Name)' on computer '$($configItem.EventChannel.PSComputerName)'", "Add ACE for 'localSystem' on folder '$($configItem.LogFilePath)'")) { Write-PSFMessage -Level Verbose -Message "Set ntfs permission for 'local service' to folder '$($destinationFolder.name)' on '$($configItem.EventChannel.PSComputerName)'" $invokeParam = @{ "ComputerName" = $configItem.EventChannel.PSComputerName "ArgumentList" = ($destinationFolder.name) "ErrorAction" = "Stop" "ErrorVariable" = "invokeErrors" } try { Invoke-PSFCommand @invokeParam -ScriptBlock { $_destinationFolderName = $args[0] $ace = New-Object System.Security.AccessControl.FileSystemAccessRule( [System.Security.Principal.SecurityIdentifier]::new("S-1-5-19").Translate([System.Security.Principal.NTAccount]).Value, 'Modify', 'ContainerInherit,ObjectInherit', 'None', 'Allow' ) $logPathACL = $_destinationFolderName | Get-Item -ErrorAction Stop | Get-ACL -ErrorAction Stop if (-not ($logPathACL.Access | Where-Object { $_.IdentityReference -like $ace.IdentityReference -and $_.FileSystemRights -like $ace.FileSystemRights -and $_.AccessControlType -like $ace.AccessControlType })) { $logPathACL.AddAccessRule($ace) $logPathACL | Set-ACL -ErrorAction Stop } } } catch { Write-PSFMessage -Level Error -Message "Unable to set ntfs permission for 'local service' to folder '$($destinationFolder.name)' on '$($configItem.EventChannel.PSComputerName)'. Message: $($_.Exception.Message)" -EnableException $true -Exception $_.Exception -ErrorRecord $_ -Target $configItem.EventChannel.PSComputerName continue } Remove-Variable -Name invokeErrors -Force -Confirm:$false -WhatIf:$false -Verbose:$false -Debug:$false -ErrorAction Ignore } } # Set compression on folder if ($configItem.CompressLogFolder) { if ($pscmdlet.ShouldProcess("EventChannel '$($configItem.EventChannel.Name)' on computer '$($configItem.EventChannel.PSComputerName)'", "Set compression '$($configItem.CompressLogFolder)' on folder '$($configItem.LogFilePath)'")) { Write-PSFMessage -Level Verbose -Message "Set compression '$($configItem.CompressLogFolder)' to folder '$($destinationFolder)' on '$($configItem.EventChannel.PSComputerName)'" $invokeParam = @{ "ComputerName" = $configItem.EventChannel.PSComputerName "ArgumentList" = ($destinationFolder, $configItem.CompressLogFolder) "ErrorAction" = "Stop" "ErrorVariable" = "invokeErrors" "WarningAction" = "SilentlyContinue" "WarningVariable" = "invokeWarnings" } try { Invoke-PSFCommand @invokeParam -ScriptBlock { $_destinationFolder = $args[0] $_Compression = $args[1] $_query = "select * from CIM_Directory where name = `"$($_destinationFolder.Name.Replace('\','\\'))`"" $_cimResult = $null $returnCodes = [ordered]@{ 0 = "Success" 2 = "Access denied" 8 = "Unspecified failure" 9 = "Invalid object" 10 = "Object already exists" 11 = "File system not NTFS" 12 = "Platform not Windows" 13 = "Drive not the same" 14 = "Directory not empty" 15 = "Sharing violation" 16 = "Invalid start file" 17 = "Privilege not held" 21 = "Invalid parameter" } if ($_Compression -eq $true -and $_destinationFolder.Compressed -eq $false) { $_cimResult = Invoke-CimMethod -Query $_query -MethodName Compress -ErrorAction Stop -Verbose:$false } elseif ($_Compression -eq $false -and $_destinationFolder.Compressed -eq $true) { $_cimResult = Invoke-CimMethod -Query $_query -MethodName Uncompress -ErrorAction Stop -Verbose:$false } else { Write-Warning "Noting to do on '$($_destinationFolder.Name)'" -WarningAction SilentlyContinue } if ($_cimResult) { if ($_cimResult.ReturnValue -notin (0, 15)) { Write-Error "Error '$($_cimResult.ReturnValue) ($($returnCodes[$_cimResult.ReturnValue]))' occured while set compression attribute '$($_Compression)'" -ErrorAction Stop } elseif ($_cimResult.ReturnValue -eq 15) { Write-Warning "Compression attribute set, but with sharing violation. Means, attribute could not be applied on all files in folder" -WarningAction SilentlyContinue } } } } catch { Write-PSFMessage -Level Error -Message "Unable to set compression to folder '$($destinationFolder.name)' on '$($configItem.EventChannel.PSComputerName)'. Message: $($_.Exception.Message)" -EnableException $true -Exception $_.Exception -ErrorRecord $_ -Target $configItem.EventChannel.PSComputerName } if ($invokeWarnings) { $invokeWarnings | ForEach-Object { Write-PSFMessage -Level Warning -Message $_ } } Remove-Variable -Name invokeErrors, invokeWarnings -Force -Confirm:$false -WhatIf:$false -Verbose:$false -Debug:$false -ErrorAction Ignore } } # Set all the other possible EventChannel configs, including "Enabled" as the last setting $valueToSet = $configItem.psobject.Properties | Where-Object Name -in ("Enabled", "MaxEventLogSize", "LogMode", "EventChannelSDDL") | Where-Object { $_.Value -is $_.TypeNameOfValue } if ($valueToSet) { $valueToSetText = [string]::Join(', ', ($valueToSet | ForEach-Object { "$($_.Name)=$($_.Value)" })) if ($pscmdlet.ShouldProcess("EventChannel '$($configItem.EventChannel.Name)' on computer '$($configItem.EventChannel.PSComputerName)'", "Set '$($valueToSetText)'")) { Write-PSFMessage -Level Verbose -Message "Set '$($valueToSetText)' to EventChannel '$($configItem.EventChannel.Name)' on '$($configItem.EventChannel.PSComputerName)'" $invokeParam = @{ "ComputerName" = $configItem.EventChannel.PSComputerName "ArgumentList" = ($configItem.EventChannel.Name, ($valueToSet | Select-Object Name, Value)) "ErrorAction" = "Stop" "ErrorVariable" = "invokeErrors" } try { Invoke-PSFCommand @invokeParam -ScriptBlock { $_eventChannelName = $args[0] $_valueToSet = $args[1] $_translateSettingToProperty = @{ "Enabled" = "IsEnabled" "MaxEventLogSize" = "MaximumSizeInBytes" "LogMode" = "LogMode" "EventChannelSDDL" = "SecurityDescriptor" } $_channel = Get-WinEvent -ListLog $_eventChannelName -Force -ErrorAction Stop $error.Clear() # backup current status $_currentIsEnabled = $_channel.IsEnabled # Disable to change settings $_channel.IsEnabled = $false $_channel.SaveChanges() # Set properties on channel foreach ($setting in ($_valueToSet | Where-Object name -NotLike "Enabled")) { $_channel.($_translateSettingToProperty[$setting.Name]) = $setting.Value } $_desiredChannelStatus = $_valueToSet | Where-Object name -Like "Enabled" if ($_desiredChannelStatus) { $_channel.IsEnabled = $_desiredChannelStatus.Value } else { $_channel.IsEnabled = $_currentIsEnabled } $_channel.SaveChanges() if ($error.Exception) { Write-Error "" -ErrorAction Stop } } } catch { Write-PSFMessage -Level Error -Message "Unable to set '$($valueToSetText)' to EventChannel '$($configItem.EventChannel.Name)' on '$($configItem.EventChannel.PSComputerName)'. Message: $($_.Exception.Message)" -EnableException $true -Exception $_.Exception -ErrorRecord $_ -Target $configItem.EventChannel.PSComputerName continue } Remove-Variable -Name invokeErrors -Force -Confirm:$false -WhatIf:$false -Verbose:$false -Debug:$false -ErrorAction Ignore } } # Output if specified if ($PassThru) { Get-WELCEventChannel -ChannelFullName $configItem.EventChannel.Name -ComputerName $configItem.EventChannel.PSComputerName -ErrorAction SilentlyContinue } } } } |