Redirecting the Warning Stream for New-PSSession
does not work as I believe it should. I am always getting the following (yellow) warning message to console regardless of what I do to try suppress / redirect it:
WARNING: Using New-PSSession with Basic Authentication is going to be deprecated soon, checkout https://aka.ms/exops-docs for using Exchange Online V2 Module which uses Modern Authentication.
What am I missing about PowerShell redirection / streams that's allowing that message to permeate through to the console / std_out?
I have tried the following, as per the wisdom of the internet:
New-PSSession *>$null ...
New-PSSession ... | Out-Null
New-PSSession *>$null ... -OutVariable x -ErrorVariable y -WarningVariable z
New-PSSession *>$null ... -WarningAction SilentlyContinue
$WarningPreference = 'SilentlyContinue'
New-PSSession ...
I've even tried taking temporary control of std_out
:
$std_out = [System.Console]::Out
$out_writer = New-Object IO.StringWriter
[System.Console]::SetOut($out_writer)
$std_err = [System.Console]::Error
$err_writer = New-Object IO.StringWriter
[System.Console]::SetOut($err_writer)
$sess = New-PSSession ...
[System.Console]::SetOut($std_out)
[System.Console]::SetError($std_err)
Along with every combination of above that I can think of, plus several more methods that I'm forgetting.
Testing each of those techniques using Invoke-Command
works for other warnings, as expected:
$std_out = [System.Console]::Out
$out_writer = New-Object IO.StringWriter
[System.Console]::SetOut($out_writer)
$std_err = [System.Console]::Error
$err_writer = New-Object IO.StringWriter
[System.Console]::SetOut($err_writer)
Invoke-Command -ScriptBlock {
Write-Error "My Error"
Write-Warning "My Warning"
[console]::WriteLine('Directly to std_out!')
} *>$null -OutVariable x -ErrorVariable y -WarningVariable z
[System.Console]::SetOut($std_out)
[System.Console]::SetError($std_err)
But nothing I have tried will suppress or redirect that message from New-PSSession
.
param (
$username,
$password
)
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$creds = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)
$URL = "https://ps.outlook.com/powershell"
New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $URL -Credential $creds -Authentication Basic -AllowRedirection
Windows 10:
Name Value
---- -----
PSVersion 7.1.0-preview.2
PSEdition Core
GitCommitId 7.1.0-preview.2
OS Microsoft Windows 10.0.18363
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Windows 10:
Name Value
---- -----
PSVersion 5.1.18362.752
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.18362.752
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Server 2019:
Name Value
---- -----
PSVersion 5.1.17763.1007
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.17763.1007
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WinRM (Identical for all systems):
Config
MaxEnvelopeSizekb = 500
MaxTimeoutms = 60000
MaxBatchItems = 32000
MaxProviderRequests = 4294967295
Client
NetworkDelayms = 5000
URLPrefix = wsman
AllowUnencrypted = false
Auth
Basic = true
Digest = true
Kerberos = true
Negotiate = true
Certificate = true
CredSSP = false
DefaultPorts
HTTP = 5985
HTTPS = 5986
TrustedHosts
Service
RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;IU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
MaxConcurrentOperations = 4294967295
MaxConcurrentOperationsPerUser = 1500
EnumerationTimeoutms = 240000
MaxConnections = 300
MaxPacketRetrievalTimeSeconds = 120
AllowUnencrypted = false
Auth
Basic = false
Kerberos = true
Negotiate = true
Certificate = false
CredSSP = false
CbtHardeningLevel = Relaxed
DefaultPorts
HTTP = 5985
HTTPS = 5986
IPv4Filter = *
IPv6Filter = *
EnableCompatibilityHttpListener = false
EnableCompatibilityHttpsListener = false
CertificateThumbprint
AllowRemoteAccess = true
Winrs
AllowRemoteShellAccess = true
IdleTimeout = 7200000
MaxConcurrentUsers = 2147483647
MaxShellRunTime = 2147483647
MaxProcessesPerShell = 2147483647
MaxMemoryPerShellMB = 2147483647
MaxShellsPerUser = 2147483647
Normally, redirecting the output works like you already tried. To be more specific:
New-PSSession -... 3> $null
would redirect your unwanted warning, as 3
describes the Warning Stream since PowerShell 3.0 (see docs).
The fact that it does not work in this particular case seems to be a bug and there has already been opened an issue here a few days ago.
There might be a possible explanation in this article:
This happens because Write-Host is not written to any stream. It's sent to the host program, and the host program decides what to do with it. The Windows PowerShell console and Windows PowerShell ISE display host messages on the console.
Well, it is not correct anymore (since PowerShell 5.0), as Write-Host
is now a wrapper for Write-Information
and thus writes to the Information Stream (6). But what is interesting, is the fact that there are host messages that are not written to any stream. This might be the case here, where you are not able to suppress a console output by redirecting all streams. So the "warning" is probably forwarded by a host message instead of using any stream.
I saw several attempts to suppress those host messages (here and here), but as far as I can tell, nothing would help in your case.
The cited article further states:
[...] messages to the host program (which can't be suppressed or redirected).
Maybe not an answer but too long for a comment. Don't ask me to explain what it does nor how it works. It was found somewhere here or somewhere else. I put it here because it seems to be related to powershell and some kind of thread interactions... I let you take what you need out of it.
Here was our context : We had to run a powershell script from a bat script. The powershell script was launching some system command (zip and so on). We had hard time to collect runtime informations the right way. As a solution we had to pass the ps1 script as a parameter of another ps1 script which we called bug.ps1
. Its content is shown below.
Here is the command in the .bat file :
powershell.exe -ExecutionPolicy Bypass -command "C:\path\to\bug.ps1" "my_script.ps1" %arg%
and here is the content of the bug.ps1 file
# <fix>
$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetField"
$objectRef = $host.GetType().GetField( "externalHostRef", $bindingFlags ).GetValue( $host )
$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetProperty"
$consoleHost = $objectRef.GetType().GetProperty( "Value", $bindingFlags ).GetValue( $objectRef, @() )
[void] $consoleHost.GetType().GetProperty( "IsStandardOutputRedirected", $bindingFlags ).GetValue( $consoleHost, @() )
$bindingFlags = [Reflection.BindingFlags] "Instance,NonPublic,GetField"
$field = $consoleHost.GetType().GetField( "standardOutputWriter", $bindingFlags )
$field.SetValue( $consoleHost, [Console]::Out )
$field2 = $consoleHost.GetType().GetField( "standardErrorWriter", $bindingFlags )
$field2.SetValue( $consoleHost, [Console]::Out )
# </fix>
invoke-expression "$args"
exit $lastexitcode
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With