I am try to download the nuget.exe via Invoke-WebRequest inside a function.
If i use Windows Powershell ISE everything works fine.
$request = Invoke-WebRequest -Uri "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -UseBasicParsing -verbose
VERBOSE: GET https://dist.nuget.org/win-x86-commandline/latest/nuget.exe with 0-byte payload
VERBOSE: received 7088048-byte response of content type application/x-msdownload
If i use VSCODE Powershell extension i get.
$request = Invoke-WebRequest -Uri "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" -UseBasicParsing -verbose
VERBOSE: GET https://dist.nuget.org/win-x86-commandline/latest/nuget.exe with 0-byte payload
Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send.
At line:1 char:12
+ $request = Invoke-WebRequest -Uri "https://dist.nuget.org/win-x86-com ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
I already tried
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
[System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls13 -bor [Net.SecurityProtocolType]::Ssl3
$PSVersionTable in ISE and VSCODE extension is identical
Name Value
---- -----
PSVersion 5.1.19041.1682
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.1682
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Is there a way to analyze/debug the difference? There must be some kind of difference in this environments.
Other download variants besides Invoke-WebRequest won't work for me, because i need the $request answer to phrase the header in some variants
The error was a previous call to...
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
Setting the callback to $true won't work and screw things up.
-SkipCertificateCheck is not availible in PSVersion 5.1.19041.1682
Added some C# code to Set the ServerCertificateValidationCallback to true if needed.
function Private-SslVerification {
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
param()
if (-not ([System.Management.Automation.PSTypeName]"SslVerification").Type)
{
Add-Type -TypeDefinition #"
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
public static class SslVerification
{
private static bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { return true; }
public static void Disable() { System.Net.ServicePointManager.ServerCertificateValidationCallback = ValidationCallback; }
public static void Enable() { System.Net.ServicePointManager.ServerCertificateValidationCallback = null; }
}
"#
}
}
function Private-Disable-SslVerification
{
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
param()
Private-SslVerification
[SslVerification]::Disable()
}
function Private-Enable-SslVerification
{
[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseApprovedVerbs", "")]
param()
Private-SslVerification
[SslVerification]::Enable()
}
Related
This two-line PS script fails if debug tracing is set to level 2:
Set-PSDebug -Trace 2
$Process = Start-Process -FilePath ping -ArgumentList localhost -NoNewWindow -PassThru -Wait
It fails with this error:
Cannot convert value to type System.String.
At line:1 char:1
+ $Process = Start-Process -FilePath ping -ArgumentList localhost -NoNe ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromAnyTypeToString
If I set -Trace 1 or no tracing, it works. If I don't try to assign $Process in -Trace 2, it works.
I wouldn't expect Set-PSDebug to modify the execution environment, but that seems to be the case here. Is this expected behavior? Or perhaps a bug in PowerShell?
Version information:
PS C:\Users\Eric> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.2364
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.2364
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
I created following simple funcion, where the parameter supports input from pipeline:
function Write-Log {
[CmdletBinding()]
param (
# Lines to log
[Parameter(Mandatory , ValueFromPipeline )]
[string[]]
$PipeLineLoglines
)
process {
Write-Host $_
}
}
If I call the function via e.g. :
"test1", "test2" | Write-Log
It works as expected, but if I'm forwarding an empty string down the pipeline I get the folowing error:
C:\> "test1", "", "test2" | Write-Log
test1
Write-Log : Cannot bind argument to parameter 'PipeLineLoglines' because it is an empty string.
At line:1 char:24
+ "test1", "", "test2" | Write-Log
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:String) [Write-Log], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Write-Log
test2
I'm using PowerShell.Core:
C:\> $PSVersionTable
Name Value
---- -----
PSVersion 6.2.0
PSEdition Core
GitCommitId 6.2.0
OS Microsoft Windows 10.0.17763
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Can someone explain why an empty string causes this error?
Thx
It's because the parameter is Mandatory, and it's considered that an empty string did not satisfy that condition. Given that there are specific validation attributes to test for that, I don't like this behavior, but that's the way it is.
There is an attribute that can help you though, [AllowEmptyString()]:
function Write-Log {
[CmdletBinding()]
param (
# Lines to log
[Parameter(Mandatory , ValueFromPipeline )]
[AllowEmptyString()]
[string[]]
$PipeLineLoglines
)
process {
Write-Host $_
}
}
I have a powershell script file, that when executed via winrm, wont get executed correctly in some windows environment.
The below script executes fine in that machine.
$ssrsEndpoint = "http://192.168.10.1/ReportServer/ReportService2010.asmx?WSDL"
$ssrsProxy = New-WebServiceProxy -Uri $ssrsEndpoint -Credential (Get-Credential)
$ssrsProxy.CreateFolder("NewFolder", "/", $null)
but, if executed via powershell remoting, it fails. ("localhost" is coming from a variable, so i don't have control over it, if the admin choose to execute the script on the same machine, it becomes localhost. So please don't ask why I'm executing the script on local machine over winrm)
$iisSess = New-PSSession -ComputerName "localhost" -Credential (Get-Credential)
Invoke-Command -Session $iisSess -ScriptBlock { [void][system.Reflection.Assembly]::LoadWithPartialName("System.Net.WebClient") }
Invoke-Command -Session $iisSess -ScriptBlock { $ssrsEndpoint = "http://192.168.10.1/ReportServer/ReportService2010.asmx?WSDL" }
Invoke-Command -Session $iisSess -ScriptBlock { $ssrsProxy = New-WebServiceProxy -Uri $ssrsEndpoint -Credential (Get-Credential) }
Invoke-Command -Session $iisSess -ScriptBlock { $ssrsProxy.CreateFolder("NewFolder", "/", $null) }
`
+ CategoryInfo : ObjectNotFound: (http://192.168.10...e2010.asmx?WSDL:Uri) [New-WebServiceProxy], WebException
+ FullyQualifiedErrorId : WebException,Microsoft.PowerShell.Commands.NewWebServiceProxy
+ PSComputerName : localhost
You cannot call a method on a null-valued expression.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
+ PSComputerName : localhost
It looks like the session didn't get the proper assemblies loaded!
Any idea?
Environment
PS C:\deployments\> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Pretty sure it is not the remoting configurations, see below the command running as a remote command.
[127.0.0.1]: PS C:\Users\Administrator\Documents> winrm get winrm/config
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
[127.0.0.1]: PS C:\Users\Administrator\Documents>
I noticed that the cmdlet Test-NetConnection was not installed on Server 2012. Since Server 2012 comes with PowerShell version 3 so I thought it might help to update to the latest version 5.1.
I did the update but the cmdlet Test-NetConnection is still not available.
Only Test-Connection is present, but I need Test-NetConnection to test ports.
How can I get Test-NetConnection now?
PS C:\Windows\system32> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.34209
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
PS C:\Windows\system32> Get-Command Test-NetConnection
Get-Command : The term 'Test-NetConnection' is not recognized as the name of a cmdlet,
function, script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
At line:1 char:1
+ Get-Command Test-NetConnection
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Test-NetConnection:String) [Get-Command], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
The availability of many cmdlets is tied to the Windows version, not the PowerShell version. If you can't upgrade your Windows version you can't have Test-NetConnection.
You could use a commandline port scanner like nmap or scanline for port tests, or you could connect to the port(s) yourself:
function Test-Port($server, $port) {
$client = New-Object Net.Sockets.TcpClient
try {
$client.Connect($server, $port)
$true
} catch {
$false
} finally {
$client.Dispose()
}
}
$ipaddress = "serverName"
$port = "portNum"
$connection = New-Object System.Net.Sockets.TcpClient($ipaddress, $port)
if ($connection.Connected) {
Write-Host "Success"
} else {
Write-Host "Failed"
}
I am trying to create a powershell script (version 2.0) to send inline images, as explained here. But something does not seem to work, or is maybe outdated or incorrect.
The following is a complete test script
$msg = new-object Net.Mail.MailMessage
$image = "testImage.png"
$imageFull = "D:\Testing\testImage.png"
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList $imageFull
$body=#"
<html>
<body>
<img src="cid:$image">
</body>
</html>
"#
which only uses an example image, and creates the following error:
The string starting:
At D:\Testing\Data\Powershell\LoadRunner\LRtestError.ps1:14 char:1
+ <<<< "#
is missing the terminator: ".
At D:\Testing\Data\Powershell\LoadRunner\LRtestError.ps1:16 char:1
+ <<<<
+ CategoryInfo : ParserError: (#
:String) [], ParseException
+ FullyQualifiedErrorId : TerminatorExpectedAtEndOfString
What is going on? Why is this error created? How to fix it?
NOTE:
If you comment out the System.Net.Mail.Attachment line, no error is created!!
Used OS: Windows Server 2008 R2 Standard (64-bit)
Full version table:
$psversiontable:
Name Value
---- -----
CLRVersion 2.0.50727.5485
BuildVersion 6.1.7601.17514
PSVersion 2.0
WSManStackVersion 2.0
PSCompatibleVersions {1.0, 2.0}
SerializationVersion 1.1.0.1
PSRemotingProtocolVersion 2.1
Make sure that #" are the first characters, and "# are last characters on the line. And that assigning the variable has it's own line $body=#". The code runs fine for me.
More information about these "Here-Strings" can be found here
$msg = new-object Net.Mail.MailMessage
$image = "testImage.png"
$imageFull = "D:\Testing\testImage.png"
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList $imageFull
$body=#"
<html>
<body>
<img src="cid:$image">
</body>
</html>
"#