mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Make -settingfile work for scriptblock logging on windows (#7631)
Make `-settingfile` work for scriptblock logging on windows
- Move EarlyParse to the first thing in the ManagedEntrance so that we don't cache the settings before we parse the settings file.
- Added a test case to prevent regression
- I'm working on more test cases. Therefore, I used the TestCases parameter.
- Changed the macOS tests back to CI as I think they are stable enough now.
This commit is contained in:
@@ -148,12 +148,9 @@ namespace Microsoft.PowerShell
|
||||
|
||||
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;
|
||||
|
||||
@@ -31,6 +31,8 @@ namespace Microsoft.PowerShell
|
||||
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
|
||||
|
||||
@@ -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: <name>' -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user