why is powershell complaining about commented lines? - powershell

I have the following comment in a powershell script:
#ERROR: Invoke-RestMethod : The underlying connection was closed: An unexpected error occurred on a send.
#EXPLANATION: PowerShell calls uses TLS 1.0 for web requests by default.
# However, Exchange is expecting a higher level of TLS, so you need to tell PowerShell to use 1.2 instead of the default of TLS 1.0
​#SOLUTION(s):
# [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
when i run the script i get this error:
s : The term 's' 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 ps1:4 char:14
+ ​#SOLUTION(s):
+ ~
+ CategoryInfo : ObjectNotFound: (s:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
why is it complaining about a comment?
if i remove (s) it then complains about SOLUTION itself...

You have it posted in your error log: + ​#SOLUTION(s):
There is a null character before the # in your code to the left of SOLUTION(s):, so it is reading the line into powershell. Just delete the row ​#SOLUTION(s): and retype it.
To check copy-and-paste the line into powershell console, should read out like below:

Related

Error downloading files with DownloadFile in powershell 2

I have the need to download files under powershell 2.
Since Invoke-WebRequest is not supported in version 2, I try to use DownloadFile but I always get the same error and I don't know how to fix it.
PS C:\Users\user> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
:: : Exception setting "SecurityProtocol": "Cannot convert null to type "System.Net.SecurityProtocolType" due to invali
d enumeration values. Specify one of the following enumeration values and try again. The possible enumeration values ar
e "Ssl3, Tls"."
At line:1 char:28
+ [Net.ServicePointManager]:: <<<< SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
PS C:\Users\user> $client = new-object System.Net.WebClient
PS C:\Users\user> $client.DownloadFile("https://web.com/test.txt", "C:\Users\user\Desktop\test.txt")
DownloadFile : Exception calling "DownloadFile" with "2" argument(s): "The underlying connection was closed: An unexpec
ted error occurred on a send."
At line:1 char:21
+ $client.DownloadFile <<<< ("https://web.com/test.txt", "C:\Users\user\Desktop\test.txt")
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
What I can do?
If you are getting an error setting the TLS version, you may want to check which protocols are available:
[Net.SecurityProtocolType]::GetValues( 'Net.SecurityProtocolType' )
However, I don't know how the protocol availability will be affected by using such an old version. Moreover, I don't know how specific protocol settings on a given system affect the availability of protocols either at large or as returned by the above command.
In fact, I would point out the error itself only reflects SSL3 & Tls. On my system when I enter an invalid enumerator the error reports Ssl3,Tls,Tls11,Tls12,Tls13 as choices. While my system is configured to disable everything below Tls12 and has no settings defined for Tls13.
The best assumption I can make is .Net 2.0 which is used with PowerShell 2.0 cannot use Tls12 as it's not present in the enumerators and based on comparison with my system the enums aren't affected by explicit enabling/disabling of protocols.
In any case, I think you have to clear up the first error before you worry about the second. The second error may well be due to the TLS incompatibility. The easiest way to do this would be to upgrade PowerShell (along with the required .Net version). PowerShell 2.0 can coexist with Windows PowerShell 5.1 though you may have to launch with the -Version 2.0 parameter. Also, make sure the engine is installed as a Windows feature. DISCLAIMER: verify all that on your own.
I know the Windows PowerShell 2.0 Engine (PowerShell-V2) was available as a feature at least as late as Windows 2012 R2.
I would also point out that PowerShell 7.x (aka PowerShell Core) can be installed side by side with Windows PowerShell. Potentially this could sidestep the aforementioned complications, allowing you to do run the task at hand...

Why do proxy commands handle errors differently

For a while, I am maintaining a PowerShell Join-Object cmdlet.
In here I am creating a few proxy commands with default parameters, as FullJoin-Object, Merge-Object and Insert-Object as described here: Proxy Functions: Spice Up Your PowerShell Core Cmdlets.
(In earlier version I was using aliases which could problems if the user creates its own aliases.)
Everything works as expected except that the error handling differs a little between the main command and the proxy command...
Taken the following MVCE, based on the following function:
Function Inverse([Int]$Number) {
Rubbish
Write-Output (1 / $Number)
}
(Where the function Rubbish doesn't exist)
Than I create a proxy function called Reverse0:
$MetaData = [System.Management.Automation.CommandMetadata](Get-Command Inverse)
$Value = [System.Management.Automation.ProxyCommand]::Create($MetaData)
$Null = New-Item -Path Function:\ -Name "Script:Inverse0" -Value $Value -Force
$PSDefaultParameterValues['Inverse0:Number'] = 0 # (Not really required for reproducing the issue)
If I run the original function Reverse 0, I get two errors:
Rubbish : The term 'Rubbish' 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:2 char:1
+ Rubbish
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (Rubbish:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Attempted to divide by zero.
At line:3 char:1
+ Write-Output (1 / $Number)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], RuntimeException
+ FullyQualifiedErrorId : RuntimeException
If run the proxy command Reverse0 (or Reverse0 0), I get only the first error:
Rubbish : The term 'Rubbish' 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:2 char:1
+ Rubbish
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (Rubbish:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CommandNotFoundException
It seems that something like the $ErrorActionPreference has changed but I checked that and it appears to be the same within both functions.
Is there and explanation for the different behavior?
Is there a way to get a Proxy Command act the same as the original command with respect to error handling?
The code that [System.Management.Automation.ProxyCommand]::Create() generates is currently (PowerShell Core 7.0.0-preview.5) flawed:
It incorrectly propagates statement-terminating errors as script-terminating errors, by using throw rather than $PSCmdlet.ThrowTerminatingError($_) in its catch blocks, causing the function to abort instantly.
If you manually correct these calls, your proxy function should behave as expected.
See this GitHub issue; the linked issue isn't specifically about this behavior, but a change has been green-lighted, and it should include a fix for it.
In concrete terms, for now, you'll have to fix the generated code manually:
Locate all try / catch statements that look like this:
try {
# ...
} catch {
throw
}
and replace them with:
try {
# ...
} catch {
$PSCmdlet.ThrowTerminatingError($_)
}

Powershell function with Try...Catch not making it into the function, because the parameter causes an error

I'm trying to use a function to confirm or deny whether or not we made it past a cmdlet without an error -- I'm running a bunch of AD/Exchange cmdlets and am storing/outputting the results to .csv at the end. I forgot to import the Exchange module, which worked to my benefit since it terminated in a way I wasn't expecting when I used Get-DistributionList.
I've tried using $? in place of the Try..Catch, forcing the EA to be stop, and storing the parameter in a variable first, but since the module isn't installed and the cmdlet isn't recognized it just stops the program.
Here's essentially what I want to do:
function Test-Success ($cmdlet){
try{
$cmdlet
"Y"
} catch {
"Err -- Perform manually."
}
}
Test-Success(Get-DistributionList)
But I get the following error, and the script stops:
Get-DistributionList : The term 'Get-DistributionList' 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:46 char:10
+ Test-Success(Get-DistributionList)
+ ~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-DistributionList:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Worst case scenario, I can just place the try...catch in every time, as it seems to work that way (example:)
try {
Get-DistributionList
"y"
} catch {
"Err -- Perform manually"
}
Any help is appreciated!I'm hoping there is a workaround so that it won't terminate the program if a cmdlet fails in this way, but I'm not terribly familiar with PowerShell and my own searches have been inconclusive.
If you are just looking to see if the command exists, you should use Get-Command like #DimplesMcGibble suggested. If you are trying to execute the command, you can pass the command name as a string and use the invoke-operator
function Test-Success ($cmdlet){
try{
& $cmdlet
"Y"
} catch {
"Err -- Perform manually."
}
}
Test-Success 'Get-DistributionList'
You should be able to use Get-Command to check for the existence of a given cmdlet without the try\catch

how connect to Azure Machine Learning Web service using PowerShell?

To use Azure Machine Learning Web service here you can find some sample code in C#, R, Python and JavaScript. I want to use it in PowerShell.
I found this tutorial, but when I am running bellow line of code, it will return error that it is not recognized:
Set-AzureMLWebServiceConnection -URI $Url -APIKey $API_key
Output:
Set-AzureMLWebServiceConnection : The term 'Set-AzureMLWebServiceConnection' 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 C:\Users\Reza\Desktop\ndbench\Azure\Automation\01_get_metrics\add_target_to_tables - runbook_01.ps1:33 char:1
+ Set-AzureMLWebServiceConnection -URI $Url -APIKey $API_key
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Set-AzureMLWebServiceConnection:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I can't found Set-AzureMLWebServiceConnection in my PowerShell command-list and I don't know how I can enable/install it.
Can you please guide me, how I can connect to Azure Machine Learning Web service using PowerShell?
The comment #gvee mentioned may be the best to use going forward though it is in beta.
However, to answer your question, use the Install-Module -Name AzureML command to get access to the Azure ML commands.

Windows Server 2012R2 Core - can't run powershell DSC

After installing a fresh Windows Server 2012R2 Core installation I created a sample DSC to test and received: Term "Setup" is not recognized as a name ...
c:\src\dsc.ps1
Configuration Setup
{
Node .
{
WindowsFeature "IIS"
{
Ensure = "Present"
Name = "Web-Server"
}
}
}
C:\src> .\dsc.ps1
C:\src> Setup
Setup : The term 'Setup' 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
+ Setup
+ ~~~~~
+ CategoryInfo : ObjectNotFound: (Setup:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
On my local Windows machine this works without any issues. Is there something I need to install or configure to make this work?
There is a small mistake in the line:
.\dsc.ps1
it should say
. .\dsc.ps1
to load the Setup configruation into the current session so you can use it.