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:
Copy 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"
}
Answer from n0rd on Stack OverflowHey 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!
windows - Powershell script if else statements - Stack Overflow
Select String - If Else Statement - Powershell
Scripting Powershell if/else statement on config match - Programming & Development - Spiceworks Community
Powershell: Conditional variable assignment in If ElseIf statement
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
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:
Copy 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.
Copyfunction 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)
}
}
if ($ISResponse -eq “y” -or “Y”) {
You have to spell that out for powershell
a switch statement could do that for you though
it’s not case sensitive, unless you tell it to.
# should be
if ($ISResponse -eq "y" -or $ISResponse -eq "Y") {
#with a switch statemtn
switch($ISResponse){
y {<#do something#>}
default{<#do something else#>}
}
So, I think we’re gonna see a few posts from me today as I continue to debug this script… If I just need to update one singular post as we go, let me know. But I’m sure each issue is going to be a little different and spread out.
I’m building upon an AD User creation script I’ve written and am in need of a little more flexibility. The company sometimes creates multiple AD user objects for a singular person depending on if they are also needed at the “sister company” (literally the building next door…) Nothing is really separated in terms of AD forests, but I do sort them into a separate container and label them so that it’s easier to find/sort. So I want the script to prompt if this is a “OtherCompany” user, and change the variables automatically.
Now, onto the script… I’m attempting to set variables inside this If / ElseIf statement, and it doesn’t appear to be working. If I run this code inside ISE and then check ($DISPLAYNAME) in the console… it displays
Test User (OtherCompany)
This happens whether or not I say “Y” or “N”.
# Set additional required variables with input given for user
$DISPLAYNAME = "$FirstName $LastName"
$SAM = $FirstName + $LastName.SubString(0,1)
$DNSROOT = '@' + (Get-ADDomain).dnsroot
$UPN = $SAM + “$DNSROOT”
Write-Host "Is this an OtherCompany user?" -ForegroundColor Yellow
$ISResponse = Read-Host "[Y] Yes, [N] No"
if ($ISResponse -eq "y" -or "Y") {
$COMPANY = "OtherCompany"
$DISPLAYNAME = "$DISPLAYNAME (OtherCompany)"
$EmployeeEmail "$FirstName.$LastName@othercompany.com"
$SAM = "$SAM-IS"
$UPN = $SAM + "$DNSROOT"
} elseif ($ISResponse -eq "n" -or "N"){
$COMPANY = "Contoso"
$EmployeeEmail = "$FirstName.$LastName@contoso.com"
}
Now, I’m seeing some conflicting information online. A few different posts say that Powershell does not support conditional assignment (interesting for a scripting language…) but that answer doesn’t hold up when I use another script I wrote. This one converts IP addresses for a Barracuda web/email filter. The only difference I can ascertain is that I’m using -like rather than -eq in this script… but this works as expected
$CIDR = Import-Csv -Path $fullimport | Select-Object CIDR,IP | ForEach-Object{
if( $_.CIDR -like 1 ) { $SubMask = "128.0.0.0"
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 2 ) { $SubMask = '192.0.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 3 ) { $SubMask = '224.0.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 4 ) { $SubMask = '240.0.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 5 ) { $SubMask = '248.0.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 6 ) { $SubMask = '252.0.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 7 ) { $SubMask = '254.0.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 8 ) { $SubMask = '255.0.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 9 ) { $SubMask = '255.128.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
} elseif ( $_.CIDR -like 10 ) { $SubMask = '255.192.0.0'
$IP = $_.IP + ',' + $SubMask + ',' + 'Block' + ', ' + $Reason + ' ' + $Country + ' (' + $Owner + ')'
etc...etc...etc...more CIDRS.. Y'know