diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs index bf198a60209..07f7dba601c 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHost.cs @@ -148,12 +148,9 @@ internal static int Start( try { - // We need to read the settings file before we create the console host string[] tempArgs = new string[args.GetLength(0)]; args.CopyTo(tempArgs, 0); - CommandLineParameterParser.EarlyParse(tempArgs); - // We might be able to ignore console host creation error if we are running in // server mode, which does not require a console. HostException hostException = null; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs index 85288357b27..63964e3e311 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ManagedEntrance.cs @@ -31,6 +31,8 @@ public sealed class UnmanagedPSEntry public static int Start(string consoleFilePath, [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 2)]string[] args, int argc) #pragma warning restore 1573 { + // We need to read the settings file before we create the console host + Microsoft.PowerShell.CommandLineParameterParser.EarlyParse(args); System.Management.Automation.Runspaces.EarlyStartup.Init(); #if !UNIX diff --git a/test/powershell/Host/Logging.Tests.ps1 b/test/powershell/Host/Logging.Tests.ps1 index 53508463d49..98e7d23d97e 100644 --- a/test/powershell/Host/Logging.Tests.ps1 +++ b/test/powershell/Host/Logging.Tests.ps1 @@ -97,6 +97,11 @@ function WriteLogSettings $values['LogLevel'] = $LogLevel.ToString() } + if($IsWindows) + { + $values["Microsoft.PowerShell:ExecutionPolicy"] = "RemoteSigned" + } + if($ScriptBlockLogging.IsPresent) { $powerShellPolicies = @{ @@ -222,7 +227,7 @@ $pid } } -Describe 'Basic os_log tests on MacOS' -Tag @('Feature','RequireSudoOnUnix') { +Describe 'Basic os_log tests on MacOS' -Tag @('CI','RequireSudoOnUnix') { BeforeAll { [bool] $IsSupportedEnvironment = $IsMacOS [bool] $persistenceEnabled = $false @@ -358,3 +363,57 @@ $pid } } } + +Describe 'Basic EventLog tests on Windows' -Tag @('CI','RequireAdminOnWindows') { + BeforeAll { + [bool] $IsSupportedEnvironment = $IsWindows + [string] $powershell = Join-Path -Path $PSHome -ChildPath 'pwsh' + $scriptBlockLoggingCases = @( + @{ + name = 'normal script block' + script = "Write-Verbose 'testheader123' ;Write-verbose 'after'" + expectedText="Write-Verbose 'testheader123' ;Write-verbose 'after'`r`n" + } + ) + + if ($IsSupportedEnvironment) + { + & "$PSHome\RegisterManifest.ps1" + } + } + + BeforeEach { + if ($IsSupportedEnvironment) + { + # generate a unique log application id + [string] $logId = [Guid]::NewGuid().ToString('N') + + $logName = 'PowerShellCore' + + # get log items after current time. + [DateTime] $after = [DateTime]::Now + Clear-PSEventLog -Name "$logName/Operational" + } + } + + It 'Verifies scriptblock logging: ' -Skip:(!$IsSupportedEnvironment) -TestCases $scriptBlockLoggingCases { + param( + [string] $script, + [string] $expectedText, + [string] $name + ) + $configFile = WriteLogSettings -ScriptBlockLogging -LogId $logId + $testFileName = 'test01.ps1' + $testScriptPath = Join-Path -Path $TestDrive -ChildPath $testFileName + $script | Out-File -FilePath $testScriptPath -Force + $null = & $powershell -NoProfile -SettingsFile $configFile -Command $testScriptPath + + $created = Wait-PSWinEvent -FilterHashtable @{ ProviderName=$logName; Id = 4104 } ` + -PropertyName Message -PropertyValue $expectedText + + $created | Should -Not -BeNullOrEmpty + $created.Properties[0].Value | Should -Be 1 + $created.Properties[1].Value | Should -Be 1 + $created.Properties[2].Value | Should -Be $expectedText + } +} diff --git a/test/tools/Modules/PSSysLog/PSSysLog.psd1 b/test/tools/Modules/PSSysLog/PSSysLog.psd1 index 14e66cb59d4..f9d67dc9f8a 100644 --- a/test/tools/Modules/PSSysLog/PSSysLog.psd1 +++ b/test/tools/Modules/PSSysLog/PSSysLog.psd1 @@ -1,10 +1,18 @@ @{ -ModuleVersion = '1.0.0' -GUID = '56b63338-045c-4697-a24b-5a756268c8b2' -Author = 'PowerShell' -CompanyName = 'Microsoft Corporation' -Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.' -Description = 'Provides a reader for powershell syslog and os_log entries' -RootModule = 'PSSysLog.psm1' -FunctionsToExport = @('Get-PSSysLog', 'Get-PSOsLog', 'Export-PSOsLog', 'Get-OsLogPersistence', 'Set-OsLogPersistence') + ModuleVersion = '1.0.0' + GUID = '56b63338-045c-4697-a24b-5a756268c8b2' + Author = 'PowerShell' + CompanyName = 'Microsoft Corporation' + Copyright = 'Copyright (c) Microsoft Corporation. All rights reserved.' + Description = 'Provides a reader for powershell syslog and os_log entries' + RootModule = 'PSSysLog.psm1' + FunctionsToExport = @( + 'Get-PSSysLog' + 'Get-PSOsLog' + 'Export-PSOsLog' + 'Get-OsLogPersistence' + 'Set-OsLogPersistence' + 'Clear-PSEventLog' + 'Wait-PSWinEvent' + ) } diff --git a/test/tools/Modules/PSSysLog/PSSysLog.psm1 b/test/tools/Modules/PSSysLog/PSSysLog.psm1 index d90d204f7fe..8c0c5779a98 100644 --- a/test/tools/Modules/PSSysLog/PSSysLog.psm1 +++ b/test/tools/Modules/PSSysLog/PSSysLog.psm1 @@ -1030,4 +1030,105 @@ function Get-OsLogPersistence #region os_log support -Export-ModuleMember -Function Get-PSSysLog, Get-PSOsLog, Export-PSOsLog, Get-OsLogPersistence, Set-OsLogPersistence + +#region eventlog support + +# utility function to clear a particular log +function Clear-PSEventLog +{ + param([Parameter(Mandatory=$true)][string]$Name) + + wevtutil cl $Name 2>$null +} + +# Waits on a windows event with a property with a particular value +function Wait-PSWinEvent +{ + param( + [Parameter()] + $FilterHashtable, + + [Parameter(ParameterSetName = "ByPropertyName")] + $propertyName, + + [Parameter(ParameterSetName = "ByPropertyIndex")] + $propertyIndex, + + [Parameter()] + $propertyValue, + + [Parameter()] + $timeout = 30, + + [Parameter()] + $pause = 1, + + [Parameter()] + [Switch] + $All + ) + +    $startTime = [DateTime]::Now + $lastFoundCount = 0; + +    do +    { +        sleep $pause + + $recordsToReturn = @() + +        foreach ($thisRecord in (get-winevent -FilterHashtable $filterHashtable -Oldest 2>$null)) +        { + if($PsCmdlet.ParameterSetName -eq "ByPropertyName") + { + if ($thisRecord."$propertyName" -like "*$propertyValue*") + { + if($All) + { + $recordsToReturn += $thisRecord + } + else + { + return $thisRecord + } + } + } + + if($PsCmdlet.ParameterSetName -eq "ByPropertyIndex") + { + if ($thisRecord.Properties[$propertyIndex].Value -eq $propertyValue) + { + if($All) + { + $recordsToReturn += $thisRecord + } + else + { + return $thisRecord + } + } + } +        } + + if($recordsToReturn.Count -gt 0) + { + if($recordsToReturn.Count -eq $lastFoundCount) + { + return $recordsToReturn + } + + $lastFoundCount = $recordsToReturn.Count + } +    } while (([DateTime]::Now - $startTime).TotalSeconds -lt $timeout) +} +#endregion eventlog support + +Export-ModuleMember -Function @( + 'Clear-PSEventLog' + 'Export-PSOsLog' + 'Get-OsLogPersistence' + 'Get-PSOsLog' + 'Get-PSSysLog' + 'Set-OsLogPersistence' + 'Wait-PSWinEvent' +)