You might use the $ExecutionContext.InvokeCommand.ExpandString method to evaluate the string expression:
$test = 5
$myCheckTest = '$test -eq 4'
$ExecutionContext.InvokeCommand.ExpandString("`
myCheckTest)")
False
$myCheckTest = '$test -eq 5'
$ExecutionContext.InvokeCommand.ExpandString("`
myCheckTest)")
True
Note that the backtick (`) prevents the first dollar to be substituted so that you actual string expression will be something like: test -eq 4)
Or in your function:
if ($ExecutionContext.InvokeCommand.ExpandString("`
myCheckTest)")) {
write-host "TEST MATCH"
} else {
write-host "TEST NO MATCH"
}
A more common way to do thing like this is, is to use a scriptblock:
$myCheckTest = {$test -eq 4}
$test = 5
if (&$myCheckTest) {
write-host "TEST MATCH"
} else {
write-host "TEST NO MATCH"
}
Answer from iRon on Stack OverflowYou might use the $ExecutionContext.InvokeCommand.ExpandString method to evaluate the string expression:
$test = 5
$myCheckTest = '$test -eq 4'
$ExecutionContext.InvokeCommand.ExpandString("`
myCheckTest)")
False
$myCheckTest = '$test -eq 5'
$ExecutionContext.InvokeCommand.ExpandString("`
myCheckTest)")
True
Note that the backtick (`) prevents the first dollar to be substituted so that you actual string expression will be something like: test -eq 4)
Or in your function:
if ($ExecutionContext.InvokeCommand.ExpandString("`
myCheckTest)")) {
write-host "TEST MATCH"
} else {
write-host "TEST NO MATCH"
}
A more common way to do thing like this is, is to use a scriptblock:
$myCheckTest = {$test -eq 4}
$test = 5
if (&$myCheckTest) {
write-host "TEST MATCH"
} else {
write-host "TEST NO MATCH"
}
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-expression
A collegae pointed me to the Invoke-Expression command:
if (Invoke-Expression $myCheckTest) {
write-host "TEST MATCH"
} else {
write-host "TEST NO MATCH"
}
This works within my actual script.
Better Way to Create If/Elseif/Else Statement
How to combine multiple conditions in a PowerShell if-statement - Stack Overflow
How to write a better if statement
windows - Powershell script if else statements - Stack Overflow
Does PowerShell support a ternary operator like other languages do?
$result = $condition ? 'TrueValue': 'FalseValue'
This is an efficient way for simple conditional assigning.
What is short-circuiting in PowerShell conditions?
Can I have multiple elseif statements in one script?
Videos
Hey Everyone!
I am fairly new to PowerShell and wanted to get some guidance on a potentially better way to utilize an If/Elseif/Else statement I have been using in an Active Directory script I made.
The following code snippet works great, but I have a feeling there is a much cleaner or efficient way of doing this. As you can see the more OU's present in the AD environment the more this elseif list grows. In the script that I used in a production environment, this list grew quite large as there was approximately 15 OUs present.
Is there a more efficient way to do this?
if ( $userdepartment -eq "IT" )
{
Get-ADUser "$($uservaluefirstletter)$($uservaluelast)".ToLower() | Move-ADObject -TargetPath 'OU=IT,OU=testlab.local Users,DC=testlab,DC=Local'
}
elseif ( $userdepartment -eq "Engineering" )
{
Get-ADUser "$($uservaluefirstletter)$($uservaluelast)".ToLower() | Move-ADObject -TargetPath 'OU=Engineering,OU=testlab.local Users,DC=testlab,DC=Local'
}
elseif ( $userdepartment -eq "Finance" )
{
Get-ADUser "$($uservaluefirstletter)$($uservaluelast)".ToLower() | Move-ADObject -TargetPath 'OU=Finance,OU=testlab.local Users,DC=testlab,DC=Local'
}
elseif ( $userdepartment -eq "Human Resources" )
{
Get-ADUser "$($uservaluefirstletter)$($uservaluelast)".ToLower() | Move-ADObject -TargetPath 'OU=Human Resources,OU=testlab.local Users,DC=testlab,DC=Local'
}
elseif ( $userdepartment -eq "Sales" )
{
Get-ADUser "$($uservaluefirstletter)$($uservaluelast)".ToLower() | Move-ADObject -TargetPath 'OU=Sales,OU=testlab.local Users,DC=testlab,DC=Local'
}
else
{
Write-Warning "Department $userdepartment could not be found."
}Thank you to anyone who takes the time to read this and gives guidance on this!
Put each set of conditions in parentheses:
if ( (A -and B) -or (C -and D) ) {
echo do X
}
If either the first or the second set of conditions must be true (but not both of them) use -xor instead of -or:
if ( (A -and B) -xor (C -and D) ) {
echo do X
}
Replace A, B, C, and D with the respective expressions.
If you want to make the code in your own answer easier to understand you can remove the duplicate code to make the if statement cleaner.
Assigning the results to variables and using those instead:
$UserName = Get-WmiObject –ComputerName $poste –Class Win32_ComputerSystem | select -ExpandProperty UserName
$WindowsVersion = Get-WmiObject -Computer $poste -Class Win32_OperatingSystem | select -ExpandProperty Version
$LogonuiProcess = Get-Process -name logonui -ComputerName $poste -ErrorAction SilentlyContinue
Then either:
if (($UserName -and $WindowsVersion -like "*10*") -or ($UserName -and -not $LogonuiProcess)) {Write-Output "do X"}
Or
if ($UserName -and $WindowsVersion -like "*10*") {Write-Output "do X"}
elseif ($UserName -and -not $LogonuiProcess) {Write-Output "do Y"}
Hi all,
I have a small script that checks a computer for different paths then runs a script / function based on if that machine has a matching drive path. This has become quite a long script with a ton of if statements…
I am looking to clean it up with a better system. Currently my code looks a little like
If (test-path xxxx) {
Do something
}
And continues on checking a bunch of different paths. Is there a better way???
If you want parameters to do something mutually exclusive and show help only if none are specified, you need to chain all your checks in a single if ... elseif ... elseif ... else chain:
if ($Username) {
$targetFolder += '\user\swmur'
}
elseif ($Scripts) {
$targetFolder += '\Desktop\Scripts'
}
elseif ($Desktop) {
$targetFolder += '\Desktop'
}
elseif ($root) {
$targetFolder += 'c:\'
}
else {
echo "
-H Display help. This is the same as not typing any options.
-U Change to the 'Username' directory
-S Change to the 'scripts' directory
-D Change to the 'desktop' directory"
}
I added some colorful commentary. This should be pretty close to what you're looking for.
function display-path {
<#
.SYNOPSIS
quick shortcut to get env:PATH
.DESCRIPTION
Call Get-ChildItem with the the -path set to "env:Path" which actually just outputs out the child items of the current folder...
.EXAMPLE
display-path | Format-List
Name : Path
Value : C:\Program Files\Eclipse Adoptium\jdk-17.0.2.8-hotspot\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPow
erShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\PuTTY\;C:\ProgramData\chocolatey\bin;C:\Program Files\Go\bin;C:\Program
Files\dotnet\;C:\Program Files\Eclipse Adoptium\jdk-17.0.2.8-hotspot\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\Syste
m32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\PuTTY\;C:\ProgramData\chocolatey\bin;C:\Program
Files\Go\bin;C:\Program Files\dotnet\;C:\Python310\Scripts;C:\Users\jedurham\AppData\Local\Programs\Microsoft VS Code\bin
.NOTES
not sure why anyone needs this
#>
Get-ChildItem -Path Env:Path
}
function folder {
<#
.SYNOPSIS
shortcut to move between folder someone uses often
.DESCRIPTION
shortcut to move between folder someone uses often.
can be used to quickly navigate to common directories.
.PARAMETER Username
Moves to the C:\Users\currentuser\ Folder.
.PARAMETER Scripts
Moves to a hard coded path called 'C:\Users\currentuser\Desktop\Scripts'
.PARAMETER Desktop
Moves to a hard coded path called 'C:\Users\currentuser\Desktop\'
.PARAMETER Help
Displays this file.
.PARAMETER root
Moves to the root of the current drive.
.EXAMPLE
folder -Username
C:> folder -U
You chose the -U flag!! Moving to C:\Users\currentuser\
.EXAMPLE
folder -Scripts
C:> folder -S
You chose the -S flag!! Moving to C:\Users\currentuser\Desktop\Scripts
.EXAMPLE
folder -Desktop
C:> folder -D
You chose the -D flag!! Moving to C:\Users\currentuser\Desktop\
.EXAMPLE
folder -root
C:\> folder -r
You chose the -R flag!! Moving to C:\
.NOTES
Needs a lot of work ....
v0.01
#>
[CmdletBinding(DefaultParameterSetName = 'Default')]
param(
[Alias('u')]
[Parameter(ParameterSetName = 'User')]
[switch]$Username
,
[Alias('s')]
[Parameter(ParameterSetName = 'Scripts')]
[switch]$Scripts
,
[Parameter(ParameterSetName = 'Desktop')]
[Alias('d')]
[switch]$Desktop
,
[Alias('h')]
[Parameter(ParameterSetName = 'help')]
[switch]$Help
,
[Alias('r')]
[Parameter(ParameterSetName = 'root')]
[switch]$root
)
$switchoutput = 'You chose the{0} flag!! Moving to {1}{2}'
if ($Username) {
## you need more comments in your code
## are you just trying to move the \user\current logged in?
## just use $env:USERPROFILE
$targetFolder = $env:USERPROFILE
$u = ' -U'
Write-Output -InputObject ($switchoutput -f $U, $targetFolder, '')
}
elseif ($Scripts) {
## a little tougher here because you need to hard code this path
## we could also ask for it ask an addendum to this switch :P
## ill do it this way
$targetFolder = $env:USERPROFILE
$s = ' -S '
## it might be better to define this else
$scriptspath = 'Desktop\Scripts'
$targetFolder = $env:USERPROFILE + $scriptspath
Write-Output -InputObject ($switchoutput -f $S, $targetFolder, '')
}
elseif ($Desktop) {
## same as above
## it might be better to define this else
$desktop = '\Desktop\'
$targetFolder = $env:USERPROFILE + $desktop
$d = ' -D '
Write-Output -InputObject ($switchoutput -f $d, $targetFolder, '')
}
elseif ($root) {
## same as other but we can use $env:homedrive for the root of C:
$targetFolder = $env:HOMEDRIVE + '\'
$r = ' -R '
Write-Output -InputObject ($switchoutput -f $r, $targetFolder, '')
}
else {
Write-Output -InputObject "
-H Display help. This is the same as not typing any options.
-U Change to the 'Username' directory
-S Change to the 'scripts' directory
-D Change to the 'desktop' directory"
-R Change to the Root of home directory"
}
if (Test-Path -Path $targetFolder) {
Set-Location -LiteralPath $targetFolder -Verbose
}
else {
Write-Output -InputObject ('{0} was not found :( exiting' -f $targetFolder)
}
}