Taking input from user changing to multiple variables powershell

93 Views Asked by At

Im trying to write a script that takes the name of a divison we have and outputs the user. For starts i have a script that will filter based on AD Description, and will spit out the desired users in said division. However these are div codes and not all users know the codes. I'd like them to be able to enter for example Head Office or Marketing, and have my scrip translate the name into a code. It's fine if the output still shows the ad descption though. So far i have it working like this

$Description = Read-Host "Enter department code EX ABC.00.A.90.AD"
Get-ADComputer -Filter "Description -like '*$Description*'" -properties description | Select Name, Description

I know i need to store the input from the user into a different variable, im just not sure how to go about doing that.

This spits out the desired output as is. But i'd like to make it a bit easier by just having them enter the name of the division. For example

Head office = ABC.00.A.90.AD Marketing planning = ABC.BC.0.90.AD

What i want is a list of divisions at the top that the script will check and still output the same result as the script above. Is that possible?

So the end result would like something like this?

$Description = Read-Host "Enter department Name EX Head Office:"
Get-ADComputer -Filter "Description -like '*$Description*'" -properties description | Select Name, Description
2

There are 2 best solutions below

0
TheMadTechnician On

If you need the user to enter something specific it has been my experience that you should provide them with a list of options, and have them choose one. Then once you give them options you can use a hashtable to map their choice to the appropriate code, and use that. For example, using your departments, you could have a hashtable like this:

$Depts = @{
    'Head office' = 'ABC.00.A.90.AD' 
    'Marketing planning' = 'ABC.BC.0.90.AD'
}

Then give them options:

"Departments:"
$Depts.keys
$DeptChoice = Read-Host "Enter department name from list above above:"

Once you get their choice you can get your AD object very similarly to what you did before:

$Description = $Depts[$DeptChoice]
Get-ADComputer -Filter "Description -like '*$Description*'" -properties description | Select Name, Description

Personally I keep a function on hand that will take an array of options and make a menu for me that the user can choose from.

Function MenuMaker{
    param(
        [parameter(Mandatory=$true,
        ValueFromPipeline = $true)][String[]]$Selections,
        [string]$Title = $null
        )

    $Width = if($Title){$Length = $Title.Length;$Length2 = $Selections|%{$_.length}|Sort -Descending|Select -First 1;$Length2,$Length|Sort -Descending|Select -First 1}else{$Selections|%{$_.length}|Sort -Descending|Select -First 1}
    $Buffer = if(($Width*1.5) -gt 78){[math]::floor((78-$width)/2)}else{[math]::floor($width/4)}
    if($Buffer -gt 6){$Buffer = 6}
    $MaxWidth = $Buffer*2+$Width+$($Selections.count).length+2
    $Menu = @()
    $Menu += "╔"+"═"*$maxwidth+"╗"
    if($Title){
        $Menu += "║"+" "*[Math]::Floor(($maxwidth-$title.Length)/2)+$Title+" "*[Math]::Ceiling(($maxwidth-$title.Length)/2)+"║"
        $Menu += "╟"+"─"*$maxwidth+"╢"
    }
    For($i=1;$i -le $Selections.count;$i++){
        $Item = "$(if ($Selections.count -gt 9 -and $i -lt 10){" "})$i`. "
        $Menu += "║"+" "*$Buffer+$Item+$Selections[$i-1]+" "*($MaxWidth-$Buffer-$Item.Length-$Selections[$i-1].Length)+"║"
    }
    $Menu += "╚"+"═"*$maxwidth+"╝"
    $menu
}

Then I would map the hashtable a little differently, using numbers for keys, and I call my function like:

$DeptNames = 'Head office','Marketing planning'
$Depts = @{
    '1' = 'ABC.00.A.90.AD' 
    '2' = 'ABC.BC.0.90.AD'
}

menumaker -Selections $DeptNames -Title 'Department Selection'
$DeptChoice = Read-Host "Select a department (1-2)"
$Description = $Depts[$DeptChoice]

Which will make a nice menu and ask them to pick one:

╔═════════════════════════════════╗
║      Department Selection       ║
╟─────────────────────────────────╢
║     1. Head office              ║
║     2. Marketing planning       ║
╚═════════════════════════════════╝
Select a department (1-2):

And in the end you get the same $Description mapping as above.

0
Santiago Squarzon On

Maybe a better way to go about it would be to have the user select the department from an UI to avoid any issues, for that you can use objects and Out-GridView -PassThru:

$map = @{
    'Head office'        = 'ABC.00.A.90.AD'
    'Marketing planning' = 'ABC.BC.0.90.AD'
    # and so on here
}

$choices = $map.GetEnumerator() | ForEach-Object {
    [pscustomobject]@{
        Department = $_.Key
        Code       = $_.Value
    }
}

$userChoice = $choices | Out-GridView -PassThru -Title 'Select Department'

if(-not $userChoice) {
    # exit early here
    return
}

$getADComputerSplat = @{
    Filter     = "Description -like '*{0}*'" -f $userChoice.Code
    Properties = 'description'
}

Get-ADComputer @getADComputerSplat | Select-Object Name, Description