I know that I can override in a script or function the StrictMode setting inherited from a higher scope. But how can I find out in a script or function what the inherited setting is?
Perhaps a small function can help:
function Get-StrictMode {
# returns the currently set StrictMode version 1, 2, 3
# or 0 if StrictMode is off.
try { $xyz = #(1); $null = ($null -eq $xyz[2])}
catch { return 3 }
try { "Not-a-Date".Year }
catch { return 2 }
try { $null = ($undefined -gt 1) }
catch { return 1 }
return 0
}
Get-StrictMode
Related
Such a weird question, but I set up this code in a playground:
let currentNumber = "1999999999"
let absNumber = abs(Double(currentNumber)!)
var digitCount = 0
if absNumber > 999999999 {
for n in currentNumber {
if n.isNumber {
digitCount += 1
} else {
break
}
print(digitCount)
}
}
As written, this code gets evaluated and my for loop runs...however, if is set my string to "-1999999999", the for loop doesn't run. The absolute value of -1999999999 is 100% greater than 999999999, so what did I miss?
The thing you did not understand is the control flow operator. You can get the expected behavior just change a single line:
if n.isNumber {
digitCount += 1
} else {
break // here change to continue
}
to this:
if n.isNumber {
digitCount += 1
} else {
continue
}
However, I highly recommend you try LLDB in an Xcode Project, either a Commandline tool or app. The stepover tool is quite useful for such a logical problem.
I am trying to pass an array to functions and fill it, and then print the results outside of the functions.
But the first function doesn't recognize the array list object I am passing to it.
Main file:
. $funcFile
$myParam = "Hello World"
$myObj = getMyObject $myParam
$myObj.myArrayList.Count # This works (outputs 0)
myFunction2 ($myObj.myArrayList)
$myObj.myArrayList.Count # This also works (outputs 0)
fncFile:
function getMyObject([String] $myParam) {
$myObj = #{
"myArrayList" = (New-Object System.Collections.ArrayList)
}
return $myObj
}
function myFunction2 ([System.Collections.ArrayList] $myArr){
$myArr.Count # This doesn't work (outputs nothing)
if($myArr -eq $null) {
Write-Host "Array List Param is null" # This condition is FALSE - nothing is printed
}
}
What am I doing wrong?
How can I use the same ArrayList in function2 and other inner functions?
If you want to pass a variable and modify it in function and use the result there are 2 ways:
Pass by value:
$arr = New-Object System.Collections.ArrayList
function FillObject([System.Collections.ArrayList]$array, [String] $myParam) {
return $array.Add($myParam)
}
$arr = FillObject -array $arr -myParam "something"
$arr.Count
Pass by reference (what you asked about)
[System.Collections.Generic.List[String]]$lst = (New-Object System.Collections.Generic.List[String]])
function FillObject([System.Collections.Generic.List[String]][ref]$list,[String] $myParam) {
$list.Add($myParam)
}
FillObject -list ([ref]$lst) -myParam "something"
$lst.Count
You have to add [ref] both in the function definition and when you pass the parameter. If this will help you - Powershell and C# rely on .NET, so their syntax is similar. C# way to use the ref:
int number = 1;
void Method(ref int refArgument)
{
refArgument = refArgument + 44;
}
Method(ref number);
I have this simple function that return some value based on the passed argument:
function GetParam($fileName)
{
if($fileName.ToLower().Contains("yes"))
{
return 1
}
elseif($fileName.ToLower().Contains("no"))
{
return 2
}
else
{
return -1
}
}
I want to call this script from another script and get its return value, in order to decide what to do next.
How can I do that ?
You have to dot source the script where the GetParam function is defined to expose it to the other script:
getparam.ps1
function GetParam($fileName)
{
if($fileName.ToLower().Contains("yes"))
{
return 1
}
elseif($fileName.ToLower().Contains("no"))
{
return 2
}
else
{
return -1
}
}
other.ps1
. .\getparam.ps1 # load the function into the current scope.
$returnValue = GetParam -fileName "yourFilename"
Note: Consider using approved Verbs and change your function name to Get-Param. Also you can omit the return keyword.
Something like this :
if(GroupExists("Admins")) // <-- How can I do this line ?
{
([ADSI]"WinNT://$_/Admins,group").add($User)
}
else
{
$Group = Read-Host 'Enter the User Group :'
([ADSI]"WinNT://$_/$Group,group").add($User)
}
You can use the Exists static method as follows:
[ADSI]::Exists("WinNT://localhost/Administrators")
To get a True/False result you can wrap into try/catch statement.
$result = try { [ADSI]::Exists("WinNT://localhost/Administrators") } catch { $False }
or in a if/then statement you'll need to wrap it inside a $()
if ( $(try {[ADSI]::Exists("WinNT://localhost/Administrators")} catch {$False}) ) {
write-host "good"
}
else {
write-host "bad"
}
I want to exit from inside a try block:
function myfunc
{
try {
# Some things
if(condition) { 'I want to go to the end of the function' }
# Some other things
}
catch {
'Whoop!'
}
# Other statements here
return $whatever
}
I tested with a break, but this doesn't work. It breaks the upper loop if any calling code is inside a loop.
An extra scriptblock around try/catch and the return in it may do this:
function myfunc($condition)
{
# Extra script block, use `return` to exit from it
.{
try {
'some things'
if($condition) { return }
'some other things'
}
catch {
'Whoop!'
}
}
'End of try/catch'
}
# It gets 'some other things' done
myfunc
# It skips 'some other things'
myfunc $true
The canonical way to do what you want is to negate the condition and put the "other things" into the "then" block.
function myfunc {
try {
# some things
if (-not condition) {
# some other things
}
} catch {
'Whoop!'
}
# other statements here
return $whatever
}
You can do like this:
function myfunc
{
try {
# Some things
if(condition)
{
goto(catch)
}
# Some other things
}
catch {
'Whoop!'
}
# Other statements here
return $whatever
}