I have a powershell script which uses 'quser' command to extract data regarding users logged onto a series of terminal servers.
I want to add a timestamp to the output files, this timestamp variable is created in a windows batch file which then calls the powershell script passes the computername and timestamp, but the powershell script is erroring with 'Missing ')' in function parameter list'
param(
[CmdletBinding()]
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = 'localhost'
[string[]]$timestamp <========= this is the line I have added
)
If I remove my added line (marked in the code above), the script runs fine
You need to add a comma between the parameters:
param(
[CmdletBinding()]
[Parameter(ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true)]
[string[]]$ComputerName = 'localhost',
[string[]]$timestamp
)
Also unless you want multiple timestamps you probably just want it to be a string rather than a string array (so [string]$timestamp).
The error message I get looks like this (except that it is in red). The first error points at the end of the localhost line then there is a knock-on error for what by that time seems to be a spurious ):
PS C:\> param(
>> [CmdletBinding()]
>> [Parameter(ValueFromPipeline=$true,
>> ValueFromPipelineByPropertyName=$true)]
>> [string[]]$ComputerName = 'localhost'
>> [string[]]$timestamp
>> )
>>
At line:5 char:38
+ [string[]]$ComputerName = 'localhost'
+ ~
Missing ')' in function parameter list.
At line:7 char:1
+ )
+ ~
Unexpected token ')' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndParenthesisInFunctionParameterList
I'm using Powershell 3 here. Other versions may show the error differently.
Related
I want to Configure the Windows Defender using Powershell.
Therefore i have a file (.txt) with the desired configuratin in it.
ScanScheduleDay = 7
DisableCatchupFullScan = True
DisableRealtimeMonitoring = False
This script will run every X hours using Taskscheduler.
It shall then scan the current configuration and check if it is different than the desired configuration in the .txt file. If there is a change i want to do sepcific things so i need to be able to know what changed.
I cant figure out, how to seperate the Confiuration name and the value from my .txt file.
if (!($config -eq $value))
{
Set-MpPreference -$config $value
}
so $config should be the first thing in the .txt (for example ScanScheduleDay) and $value should be the value after the " = " (for example 7)
The easiest way of doing that is to read the config text file and convert it into a hashtable. Then compare what the current setting is to what is desired:
# read the desired config text file and convert to Hashtable
$txt = Get-Content -Path 'D:\DefenderConfig.txt' -Raw | ConvertFrom-StringData
# get the current configuration
$currentConfig = Get-MpPreference
# loop through the settings from the text file and report the differences
$txt.GetEnumerator() | ForEach-Object {
$currentValue = $currentConfig.$($_.Name)
if ($_.Value -ne $currentValue) {
# there is a difference found.
# for demo, just show on screen
Write-Host "Current value for '$($_.Name)': $currentValue - Desired: $($_.Value)"
}
}
Output:
Current value for 'DisableCatchupFullScan': False - Desired: True
Current value for 'ScanScheduleDay': 0 - Desired: 7
Now that i have that sorted i try to reset any settings that dont match my .txt file.
I have the Name of the Setting (ScanScheduleDay as an example) in a variable $conname
Also the desired value is in $currentValue
i get the error:
Set-MpPreference : A positional parameter cannot be found that accepts argument '-ScanScheduleDay'.
At C:\temp\defendertest\Defendersettings.ps1:120 char:1
+ Set-MpPreference "-$conname" $currentValue
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-MpPreference], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Set-MpPreference
Cant i just use a variable as the parameter?
My Python2.7 and pypy(using virtualenv) are all under windows 10 environment. From a README file in simulation software, below includes a 'for loop" script in Bash command. How would I convert below 'for loop" (three lines) Bash commands into equivalent Windows 10 Powershell commands?
"It's better to run several processes in parallel, for instance:
$ for i in {1..10}; do
$ time $pypy epto.py conf_epto/ $i > conf_epto/run-$i.log $
$ done
And then to obtain stats for all runs:
$pypy genStats.py conf_epto 10
This will output the stats to stdout and also generate dumps in gnuplot format."
I tried to run Powershell commands but face error:
(my-pypy-env) PS C:\Users\Acer\dev\pypy27home\my-pypy-env\SimpleDA-master> for ( $i = 1; $i -le 10; $i++) {
>> $pypy epto.py conf_epto/ $i > conf_epto/run-$i.log $
>> done}
At line:2 char:7
+ $pypy epto.py conf_epto/ $i > conf_epto/run-$i.log $
+ ~~~~~~~
Unexpected token 'epto.py' in expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnexpectedToken
foreach ($i in 1..10) {
Measure-Command { & $pypy epto.py conf_epto/ $i > conf_epto/run-$i.log } | Out-Host
}
& $pypy genStats.py conf_epto 10
foreach ($i in 1..10) loops over the elements of array 1..10, created with PowerShell's range operator (..); the body of compound statements such as foreach is always enclosed in { ... } in PowerShell.
Measure-Command is PowerShell's equivalent to Bash's time builtin; the command whose execution to measure is passed as a script block ({ ... }).
The command inside the script block basically works the same as in Bash, except that in Windows PowerShell > creates "Unicode" - UTF16-LE - files by default (in PowerShell Core it is UTF-8 without a BOM). > is an effective alias of the Out-File cmdlet; to use a different encoding, pipe to it and use the -Encoding parameter (e.g., ... | Out-File -Encoding utf8 conf_epto/run-$i.log), though note that in Windows PowerShell -Encoding utf8 invariably creates a UTF-8 file with a BOM.
time outputs its result directly to the terminal rather than to stdout; so does Out-Host; it bypasses PowerShell's stdout equivalent, the success [output] stream.
PowerShell requires use of &, the call operator, for executing a command whose name or path is specified as a variable ($pypy); this requirement stems from PowerShell having two distinct parsing modes.
I have bellow script
$ErrorActionPreference = "Stop";
while($true) {
try {
Write-Host "Step 1";
Dir C:\arts #Error
Write-Host "Step 2";
exit 0
break;
}
catch {
"Error in " + $_.InvocationInfo.ScriptName + " at line: " + $_.InvocationInfo.ScriptLineNumber + ", offset: " + $_.InvocationInfo.OffsetInLine + ".";
$Error
exit 1
break;
}
}
It stops on Dir C:\arts line and that is good for me. As I understood it happens cos I have line $ErrorActionPreference = "Stop"; at the beginning.
I also have some docker params
Param(
[Parameter(Mandatory=$True,ParameterSetName="Compose")]
[switch]$Compose,
[Parameter(Mandatory=$True,ParameterSetName="ComposeForDebug")]
[switch]$ComposeForDebug,
[Parameter(Mandatory=$True,ParameterSetName="StartDebugging")]
[switch]$StartDebugging,
[Parameter(Mandatory=$True,ParameterSetName="Build")]
[switch]$Build,
[Parameter(Mandatory=$True,ParameterSetName="Clean")]
[switch]$Clean,
[parameter(ParameterSetName="Compose")]
[Parameter(ParameterSetName="ComposeForDebug")]
[parameter(ParameterSetName="Build")]
[parameter(ParameterSetName="Clean")]
[ValidateNotNullOrEmpty()]
[String]$Environment = "Debug"
)
If I put $ErrorActionPreference = "Stop" line before docker params I will have error Cannot convert value "System.String" to type "System.Management.Automation.SwitchParameter". Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.
In case if I put $ErrorActionPreference = "Stop"; line after docker params, script is continued to run and that is not that I want.
I do not know what I need to do here, so I will be grateful for any help
$ErrorActionPreference doesn't work with command line utilities like docker as they don't throw exceptions in PowerShell. You would have to use returncode/errorlevel or parse the output to handle those type of errors. Useful automatic variables:
$?
Contains the execution status of the last operation. It contains
TRUE if the last operation succeeded and FALSE if it failed.
$LastExitCode
Contains the exit code of the last Windows-based program that was run. Same as %errorlevel% in cmd.
If you detect an error, you can throw an exception to stop the script or use something like exit to stop the script. Example:
function Test-Error {
$ErrorActionPreference = "Stop"
Write-Host Before
ping -n 1 123.123.123.123
#If last command was not successfull.
#You can also have checked $lastexitcode, output etc.
if($? -eq $false) {
#Throw terminating error
#throw "Error"
#Or since we've chosen to stop on non-terminating errors, we could use:
Write-Error -ErrorId $LASTEXITCODE -Message "Ping failed"
}
Write-Host After
}
Test-Error
Output:
Before
Pinging 123.123.123.123 with 32 bytes of data:
Request timed out.
Ping statistics for 123.123.123.123:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
Test-Error : Ping failed
At line:22 char:1
+ Test-Error
+ ~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : 1,Test-Error
If you're creating a advanced function, you could set the default ErrorAction for the scope of the cmdlet like this:
function Test-Error {
[CmdLetBinding()]
param(
$Name = "World"
)
#If -ErrorAction is not specified by the user, use Stop for the scope of the function
if(-not $MyInvocation.BoundParameters.ContainsKey("ErrorAction")) { $ErrorActionPreference = "Stop" }
"Hello $Name ! My ErrorAction is: $ErrorActionPreference"
}
PS > $ErrorActionPreference
Continue
PS > Test-Error -ErrorAction Ignore
Hello World ! My ErrorAction is: Ignore
PS > Test-Error
Hello World ! My ErrorAction is: Stop
In my Powershell script, I use "rmtshare.exe" to get information about share level permission. The "rmtshare.exe" can run perfectly under CMD environment with following command:
rmtshare.exe \\fs-sw-206\"C&C FQT"
However, when I bring it to powershell environment. I can't figure out how to escape the space and the ampersand. Here is what I have tried so far which it is not working:
$rmtShare = "C:\rmtshare.exe"
$ServerName = "fs-sw-206"
$ShareName = "C&C FQT"
Invoke-Expression ($rmtShare + " " + "\\" + $ServerName + "\" + $ShareName)
The script above will give error message from the CMD, it said "if a sharename or path contains spaces, it should be enclosed in quotes".
If I changed the last line to this:
Invoke-Expression ($rmtShare + " " + "\\" + $ServerName + "\" + "'"+'"'+"'" + $ShareName +"'"+'"'+"'")
The error message was from Powershell itself, it said "The ampersand (&) character is not allowed". NOTE: if there is no ampersand, it works. So, now I am stuck because I need to escape both characters at the same time.
Please offer your solution.
You may need to download the rmtshare.exe to test out yourself. Download site: (https://www.symantec.com/connect/downloads/remove-folder-share-remote-computer)
so, here is the code in Powershell that overcame the problem - escape space and ampersand in same time in powershell script that execute CMD
$s = " "
$q = '"'
$Verbatim = '--%'
$rmtShare = "C:\rmtshare.exe"
$ServerName = "fs-sw-206"
$ShareName = "C&C FQT"
Invoke-Expression ($rmtShare +$s+$Verbatim+$s+"\\"+$ServerName+"\"+$q+$ShareName+$q)
There should be other solutions as well. Please post if you know it.
I try to call on post-deployment action a powerShell script with an array parameter, but without success.
Here is the script:
param(
[string[]]$ModelNameList = "DefaultModelName"
)
Write-Host "Number of Models is: $($ModelNameList.Count)"
and this is the post-deployment command line:
%windir%\sysnative\windowspowershell\v1.0\powershell -File "$(ProjectDir)Scripts\Post_Deployment\Script.Post-Deployment.ps1" -ModelNameList "m2","m1"
Result : Number of Models is: 1
Running the same script in SharePoint2010 Management Shell return the correct result.
Result : Number of Models is: 2
CMD doesn't know anything about PowerShell arrays, so it passes "m2","m1" into the powershell script as a single string. You can see that when you add
Write-Host $ModelNameList[0]
Write-Host $ModelNameList[0].GetType()
to your PowerShell script. I think you have to split the argument inside your script:
if ($ModelNameList[0] -match ',') {
$ModelNameList = $ModelNameList[0].Split(',')
}