Powershell while loop - powershell

The below code keeps getting stuck in a loop when it gets to
$choice = read-host "Are you sure you want to disable the following user? (Y/N)" "$name"
I type in y and it keeps looping that question.
I've tried a do while & single IF statement. Any ideas on how to stop this loop?
$choice = ""
$User = read-host "enter username"
$Name = Get-ADuser -Identity $Username | Select-Object Name
while ($choice -notmatch "y/n"){
$choice = read-host "Are you sure you want to disable the following user? (Y/N)" "$name"
If ($Choice -eq"Y"){
Disable-ADAccount $Username
}
}

You need to use the pipe for an or statement to work not a slash
This...
while ($choice -notmatch "y/n"
...should be this...
while ($choice -notmatch "y|n"
This is wrong, because you do not have a populated variable in the posted code to use...
Disable-ADAccount $Username
... based on your code, it should be this...
Disable-ADAccount $User
No need to seperate the variable in the choice statment. Just do this.
$choice = read-host "Are you sure you want to disable the following user? (Y or N) $name"
Example:
$choice = ""
$User = read-host "enter username"
$Name = $User
while ($choice -notmatch "y|n")
{
$choice = read-host "Are you sure you want to disable the following user? (Y/N) $Name"
If ($Choice -eq "y")
{ $User }
}
enter username: test
Are you sure you want to disable the following user? (Y/N) test: u
Are you sure you want to disable the following user? (Y/N) test: u
Are you sure you want to disable the following user? (Y/N) test: y
test
enter username: test1
Are you sure you want to disable the following user? (Y/N) test1: h
Are you sure you want to disable the following user? (Y/N) test1: h
Are you sure you want to disable the following user? (Y/N) test1: n

Related

Can you loop if statements in PowerShell?

First off, let me apologize if this is a stupid simple solution. I am currently in college and I am working on a project to create an AD enviroment with users, OUs, GPOs etc. I am hoping there's a way to loop the if statement asking if you want to create an Organizational Unit so instead of repeating the same lines, it would look cleaner and be more usable in a real world scenario.
Currently, I am using: But, if you wanted to create more than the two prompts, you couldn't.
#Create OUs
$Create_OU1= Read-Host -Prompt "Do you want to create any Organizational Units? Y/N"
if ($Create_OU1 -eq "Y" -or $Create_OU1 -eq "Yes") {
New-ADOrganizationalUnit
}
$Create_OU2= Read-Host -Prompt "Do you want to create any additional Organizational Units? Y/N"
if ($Create_OU2 -eq "Y" -or $Create_OU2 -eq "Yes") {
New-ADOrganizationalUnit
}
Read-Host -Prompt "Do you want to create any additional Organizational Units? Y/N"
Doing it with a do loop and PromptForChoice Method the code would look like this:
$prompt = {
param($message)
$Host.UI.PromptForChoice($null, $message, ('&Yes', '&No'), 0)
}
$message1 = 'Do you want to create any Organizational Units?'
$message2 = 'Do you want to create any additional Organizational Units?'
if((& $prompt $message1) -eq 0) {
do {
New-ADOrganizationalUnit
}
while((& $prompt $message2) -eq 0)
}

How to validate 2 inputs in Powershell and only proceed when both inputs are validated

Trying to write a script in Powershell that needs to validate 2 User Inputs before applying policies to the correct entries. With the basic script I wrote, It Validates the 1st Entry which is the User ID in the Teams Tenant. Then Validates the 2nd entry which is the telephone number using the validate regex. The problem I am having is that the policies Do not get applied when the correct information is applied. It skips that part and states a Warning and asks to check another profile.
Connect-MicrosoftTeams
do {
try {
# 1st User Entry to check UserID
$upnentry = Read-Host 'Enter the User Principle Name'
# Validate in Teams Tenant if this ID exists, If Not,
# prompt to enter a valid entry again
$csu = Get-CsOnlineUser -Identity $upnentry -ErrorAction Stop
$csu | Format-List IsSipEnabled, Displ*
Write-Host 'User ID has been verified correctly!'
# 2nd User Entry to check for valid Telephone Number
$phoneinputblock = {
try
{
[validatescript({[regex]::Match($_,'^27\d{9}$').Length -eq 11})]
$phoneUserInput = Read-Host "`nEnter Telephone Number"
$phoneUserInput
}
catch{ Write-Warning "Incorrect Format for Telephone Number!"
& $phoneinputBlock
}
}
$phoneuserInput = & $phoneinputBlock
Write-Host 'Telephone Number is in the correct format!'
Set-CsPhoneNumberAssignment -Identity $user -PhoneNumber
$phonenumberinput -PhoneNumberType DirectRouting
Grant-CsOnlineVoiceRoutingPolicy -PolicyName VRP- International -Identity $upnentry
Write-host "Policies applied successfully for : $upnentry" - ForegroundColor Green
}
catch { Write-Warning "You've entered an invalid UserID: $upnentry"
}
} until($Host.UI.PromptForChoice('', 'Do you want to check another Users Profile?',
('&Yes', '&No'), 0))
I would not perform the two tests inside nested try--catch blocks like that, but instead use a boolean variable to keep track of the result from the first test and only if that is true proceed with the rest.
Something like this:
Connect-MicrosoftTeams
do {
$testID = $false
try {
# 1st User Entry to check UserID
$upnentry = Read-Host 'Enter the User Principle Name'
# Validate in Teams Tenant if this ID exists, If Not,
# prompt to enter a valid entry again
$csu = Get-CsOnlineUser -Identity $upnentry -ErrorAction Stop
$csu | Format-List IsSipEnabled, Displ*
Write-Host 'User ID has been verified correctly!'
$testID = $true
}
catch { Write-Warning "You've entered an invalid UserID: $upnentry"}
if ($testID) {
# 2nd User Entry to check for valid Telephone Number
while ($true) {
$phoneUserInput = Read-Host "`r`nEnter Telephone Number"
if ([regex]::Match($phoneUserInput,'^27\d{9}$').Length -eq 11) {
Write-Host 'Telephone Number is in the correct format!'
break # exit the loop
}
# here we have a wrong phone number, so ask again
Write-Host "`r`nThe Telephone Number is in the wrong format. Should start with 27 followed by nine digits" -ForegroundColor Red
if ((Read-Host "Do you want to stop here (Yes/No) ?") -match '^Y') { # exit the script
exit
}
}
# here we know both entries are correct, so proceed setting the phone number
try {
Set-CsPhoneNumberAssignment -Identity $upnentry -PhoneNumber $phoneUserInput -PhoneNumberType DirectRouting -ErrorAction Stop
Grant-CsOnlineVoiceRoutingPolicy -PolicyName 'VRP- International' -Identity $upnentry -ErrorAction Stop
Write-host "Policies applied successfully for: $upnentry" - ForegroundColor Green
}
catch {
Write-Warning "Error setting the phone number: $($_.Exception.Message)"
}
}
} until ($Host.UI.PromptForChoice('', 'Do you want to check another Users Profile?', ('&Yes', '&No'), 0))

Powershell - Basic Script not working Regarding Get-AdUser

I want to Get-ADUser and then compare that to whatever the user has inserted.
I would greatly appreciative if anyone could help me fix this.
$user1 = Read-Host "Enter the first username"
$GetUser = Get-ADUser -Filter {SamAccountName- eq $user1}
if ($user1 -ne $GetUser){
Write-Host "It does not match our records. Please try again later" -ForeGroundColor Red
}
elseif ($User1 -eq $GetUser){
Write-Host "It matches our records" -ForegroundColor Green
}
You can just test that there is a return from Get-ADUser, if there's no match nothing is returned.
I would also use Identity (instead of Filter) as it accepts both SamAccountName and DN.
A distinguished name
A GUID (objectGUID)
A security identifier (objectSid)
A SAM account name (sAMAccountName)
This simplifies your code to:
$user1 = Read-Host "Enter the first username"
if (Get-ADUser -Identity $user1){
Write-Host "It matches our records" -ForegroundColor Green
}
else {
Write-Host "It does not match our records. Please try again later" -ForeGroundColor Red
}

Automatically Adding a Number to variable in Powershell

I have looked at some sites online and browsed a few answers here and I have had no luck with my question.
I have a PowerShell script to automate account creations using information entered in the host. My question is this, how can I set my script to automatically add a number at the end of the submitted data if it already exists? Code block is below:
$Username = Read-host "Enter Desired Username"
#Test
IF(!(Get-ADUser -Identity $Username))
{ Write-Host "$username exists. Adding number.
HERE IS THE CODE I AM LOOKING FOR TO TAKE THE $Username and automatically add the number at the end.
}
If this was already answered, please send me the link and I'll mark this as answered but if not, any suggestions would be great.
Thanks!
Since this script isn't being automatically run and there is user input, I would suggest just re-prompting the user if the name is taken:
Do
{
$Username = Read-Host -Prompt 'Enter desired username'
} While (Get-ADUser -Identity $Username)
Alternatively:
$Username = Read-Host -Prompt 'Enter desired username'
While (Get-ADUser -Identity $Username)
{
"Username '$Username' taken!"
$Username = Read-Host -Prompt 'Enter desired username'
}
To supplement the other answer, you could also do something like this to determine the next available username:
$Username = Read-Host -Prompt 'Enter desired username'
$TestUsername = $Username
$i = 1
While (Get-ADUser -Identity $TestUsername)
{
Write-Warning "$TestUsername is taken"
$TestUsername = $Username + $i++
}
"The next available username is $TestUsername"
Within the loop the ++ operator is used to increment the counter variable $i and appends that to the original username each time the loop repeats. Note that it is appended first then incremented second, so we start at 1.
I've written such a script. My logic is:
Before creating an account, query this account firstly
If the account exists, suffix a 2 digits number (from 01, format by "{0:d2}" -f
Query the suffixed account, repeat step 1 and 2, till the account doesn't exist (use recursive function).
It's the code:
$seq = 1
Function Check-Existing {
param(
[Parameter(Mandatory=$true)]
[string]$Account
)
while (Get-ADUser $Account){
$suffix = "{0:d2}" -f $seq
$Account = $Account + $suffix
$seq++
return $Account
}
Check-Existing -Account $Account
}
(I'll double check the code on Monday)

PowerShell. Clear previous Read-Host

I have the following code in which the user has to enter either Y or N. If it's ENTER or anything else it requests again. The request is made every time on the same line.
My problem is that after I enter a wrong answer, when I'm prompted again I have to write over my previous answer.
I've tried clearing the keyboard buffer before Read-Host with no luck. I don't want to use Clear-Host or a new line, it has to be on the same line.
My question is, can I have a clean line after a wrong answer?
function clrkb
{
while($Host.UI.RawUI.KeyAvailable)
{
$Host.UI.RawUI.ReadKey() | Out-Null
}
}
$y_temp +=1;
do
{
clrkb
[Console]::SetCursorPosition(2,$y_temp);write-host Is this a service job? Y/N -f Magenta;[Console]::SetCursorPosition(29,$y_temp);$sj = read-host
}until($sj -eq "Y" -or $sj -eq "N")
function clrkb{
while(
$Host.UI.RawUI.KeyAvailable){$Host.UI.RawUI.ReadKey() | Out-Null
}
}
$y_temp +=1;
do{
clrkb
[Console]::SetCursorPosition(2,$y_temp);write-host Is this a service job? Y/N -f Magenta;[Console]::SetCursorPosition(29,$y_temp);[Console]::Write(' ' * [Console]::WindowWidth);[Console]::SetCursorPosition(29,$y_temp);$sj = read-host
}until($sj -eq "Y" -or $sj -eq "N")
Use spaces to overwrite wrong answer.
Maybe [Console]::WindowWidth is not always big enough, so $sj.length can be used instead.
function clrkb{
while(
$Host.UI.RawUI.KeyAvailable){$Host.UI.RawUI.ReadKey() | Out-Null
}
}
$y_temp +=1;
$sj='';
do{
clrkb
[Console]::SetCursorPosition(2,$y_temp);write-host Is this a service job? Y/N -f Magenta;[Console]::SetCursorPosition(29,$y_temp);[Console]::Write(' ' * $sj.length);[Console]::SetCursorPosition(29,$y_temp);$sj = read-host
}until($sj -eq "Y" -or $sj -eq "N")