Enable Users Script - powershell

I am attempting to make a script that will check a variety of settings and ask permission before changing them. I'm writing this for non-IT users, so each of the user checks is a pop out message box. I thought that this part of the code was working, but now not so much. I'm getting an error indicating the user wasn't found, but that's what I'm trying to use as an if-else trigger. Error Message
As always, thanks to all the saints out there saving my behind from this.
PS: I know its not overly secure to have the password hard coded into the script, and if it were up to me, we wouldn't do it this way. But this is how the boss wants it for now.
#User Group
If (Get-LocalGroup -Name "Koko Svc"){
Write-Host "User Group Koko Svc already exists"
}
Else{
$UserConfirm=[System.Windows.Forms.MessageBox]::Show("Would you like to create the Local Group `"Koko Svc`"?","`"Koko Svc`" Group Not Found",[System.Windows.Forms.MessageBoxButtons]::YesNoCancel)
switch ($UserConfirm){
"Yes" {
write-host "User agreed to create `"Koko Svc`""
New-LocalGroup -Name 'Koko Svc' -Description 'KoKo Svc'
}
"No" {
write-host "User declined to create `"Koko Svc`""
break
}
"Cancel" {
write-host "User stopped Settings Check"
exit
}
}
}
#Users
If (Get-LocalUser -Name "KoKo Svc"){
Write-Host "User Koko Svc already exists"
}
Else{
$UserConfirm=[System.Windows.Forms.MessageBox]::Show("Would you like to create the User `"Koko Svc`"?","`"Koko Svc`" User Not Found",[System.Windows.Forms.MessageBoxButtons]::YesNoCancel)
switch ($UserConfirm){
"Yes" {
write-host "User agreed to create `"Koko Svc`""
$Password1 = ConvertTo-SecureString "FooBar" -AsPlainText -Force
New-LocalUser "KoKo Svc" -Password $Password1 -FullName "KoKo Svc"
Add-LocalGroupMember -Group 'Administrators' -Member ('KoKo Svc','Administrators')
Add-LocalGroupMember -Group 'Koko Svc' -Member ('KoKo Svc','KoKo Svc')
}
"No" {
write-host "User declined to create `"Koko Svc`""
break
}
"Cancel" {
write-host "User stopped Settings Check"
exit
}
}
}
If (Get-LocalUser -Name "Valued Customer"){
Write-Host "User Valued Customer already exists"
}
Else{
$UserConfirm=[System.Windows.Forms.MessageBox]::Show("Would you like to create the User `"Valued Customer`"?","`"Valued Customer`" User Not Found",[System.Windows.Forms.MessageBoxButtons]::YesNoCancel)
switch ($UserConfirm){
"Yes" {
write-host "User agreed to create `"Valued Customer`""
$Password2 = ConvertTo-SecureString "BarFoo" -AsPlainText -Force
New-LocalUser "Valued Customer" -Password $Password2 -FullName "Valued Customer"
Add-LocalGroupMember -Group 'Administrators' -Member ('Valued Customer','Administrators')
Add-LocalGroupMember -Group 'Koko Svc' -Member ('Valued Customer','KoKo Svc')
}
"No" {
write-host "User declined to create `"Valued Customer`""
break
}
"Cancel" {
write-host "User stopped Settings Check"
exit
}
}
}

You could change it to
If (Get-LocalUser -Name "Valued Customer" -ErrorAction SilentlyContinue){
Write-Host User Valued Customer already exists
}
Else{
write-host available
}
That way only if it produces an output it will run the if portion.

A few things.
You can't use the same name for both a group and a user, which is why you get the error
The name KoKo Svc is already in use
On commands that you expect to fail, and want to take action if it does, use try/catch blocks. You can go the -ErrorAction SilentlyContinue route, but in my opinion, that's sloppy and inelegant. You'll just be ignoring the error, instead of taking action on it. I would do something like this
try
{
Get-LocalUser -Name $Name -ErrorAction Stop
$exists = $true
Write-Host "User $Name already exists"
}
catch [Microsoft.PowerShell.Commands.UserNotFoundException]
{
$exists = $false
}
then DRY the code up by tossing it in a simple function or two, so I'm not copy pasting a big chunk every time
function Test-LocalUser([string]$Name)
{
try
{
Get-LocalUser -Name $Name -ErrorAction Stop
$exists = $true
Write-Host "User $Name already exists"
}
catch [Microsoft.PowerShell.Commands.UserNotFoundException]
{
$exists = $false
}
return $exists
}
function Test-LocalGroup([string]$Name)
{
try
{
Get-LocalGroup -Name $Name -ErrorAction Stop
$exists = $true
Write-Host "Group $Name already exists"
}
catch [Microsoft.PowerShell.Commands.GroupNotFoundException]
{
$exists = $false
}
return $exists
}
Then for your code, you can do something like this
$group = "Koko Svc group"
if(!(Test-LocalGroup -Name $group))
{
$UserConfirm=[System.Windows.Forms.MessageBox]::Show("Would you like to create the Local Group `"$group`"?","`"$group`" Group Not Found",[System.Windows.Forms.MessageBoxButtons]::YesNoCancel)
switch ($UserConfirm)
{
"Yes"
{
write-host "User agreed to create `"$group`""
New-LocalGroup -Name $group -Description $group
}
"No"
{
write-host "User declined to create `"$group`""
break
}
"Cancel"
{
write-host "User stopped Settings Check"
exit
}
}
}
#Users
$user = "Koko Svc user"
if(!(Test-LocalUser -Name "Koko Svc"))
{
$UserConfirm=[System.Windows.Forms.MessageBox]::Show("Would you like to create the User `"$user`"?","`"$user`" User Not Found",[System.Windows.Forms.MessageBoxButtons]::YesNoCancel)
switch ($UserConfirm)
{
"Yes"
{
write-host "User agreed to create `"$user`""
$Password1 = ConvertTo-SecureString "FooBarasdasdasdasdadad2334342342!!!" -AsPlainText -Force
New-LocalUser "$user" -Password $Password1 -FullName "$user"
Add-LocalGroupMember -Group 'Administrators' -Member ($user,'Administrators')
Add-LocalGroupMember -Group $group -Member ($user,$group)
}
"No"
{
write-host "User declined to create `"$user`""
break
}
"Cancel"
{
write-host "User stopped Settings Check"
exit
}
}
}
I would also recommend tossing the user creation portion into a function as well, to reduce all the copy-paste code. If this is something designed for other people, making it easy to maintain is a priority. By making functions out of your repeated code, you only have to make a change in one place, rather than every copy/pasted section. If you want to see an example of the user creation portion in a function, lemme know and I'll toss it in an edit.

Related

How do I use a switch statement with while loop

I am trying to add a user to the Remote Desktop group using Powershell.
It seems it's not breaking the loop and doesn't execute further statements.
Can you please help me where the issue is:
$remote = ""
While($remote -ne "Y" ){
$remote = read-host "Do you need to add anyone to the Remote Desktop group (y/n)?"
Switch ($remote)
{
Y {
$remoteuser = ""
while ( ($remoteuser -eq "") -or ($UserExists -eq $false) )
{
$remoteuser = Read-Host "Enter the username that needs to be in the group"
Write-Host "User inputted $remoteuser"
sleep -Seconds 2
try {
Get-ADUser -Identity $remoteuser -Server <server-FQDN>
$UserExists = $true
Write-Host "$remoteuser found!"
sleep 5
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityResolutionException] {
Write-Host "User does not exist."
$UserExists = $false
}
catch {
Write-Host "Username is blank"
$UserExists = $false
}
}
}
N {Write-Host "No user accounts will be added to the Remote Desktop Users group. Restart your PC."}
default {Write-Host "Only Y/N are Valid responses"}
}
}
<further statements>

Statements has no effect (if/else) in PS

I'm working on a script that gets executed only if X account is found, but is not working as intended the if/else statements get bypassed and the code gets executed anyways. What am i doing wrong?
$Account = "XXXX"
Get-LocalUser -name $Account
if (($Account) -eq $true) {
} else {
Write-host -foreground cyan "I found it"
}
exit
If i ran the script as is it will output the text on the console even tho "XXX" account is not present, could something like that can be done?
This should do it:
$Account = "XXXX"
$AccountObject=Get-LocalUser -name $Account -ErrorAction SilentlyContinue
if (($AccountObject)) {
Write-host -foreground cyan "I found it"
} else {
Write-host -foreground cyan "No luck"
}
The issue with the sniplet provided - the return of Get-LocalUser was not used. Instead you were using a string value which is always set therefore true - as you set it to 'XXXX' in your first line.
As Bill_Stewart explains, the reason that the else block is reached is because ($Account) -eq $true evaluates to $false unless the account name is "true".
In order to test whether Get-LocalUser succeeded or failed to retrieve the user account, you can instead inspect the $? automatic variable - it will have a value of $false only if the previous command threw an error:
$AccountName = "nonExistingUser"
# Try to fetch existing user account, don't show any errors to the user
$UserAccount = Get-LocalUser -Name $AccountName -ErrorAction SilentlyContinue
# Test if the call was successful
if($?) {
Write-Host "Found account named '$AccountName'!" -ForegroundColor Cyan
$UserAccount
} else {
Write-Host "No account named '$AccountName' was found ..." -ForegroundColor Magenta
}

If error, skip to next in Powershell (Microsoft Teams)

Good evening,
I have written a piece of code in Powershell that takes a .csv file as input, and create a new
Microsoft Team with the channels and users in the .csv
The script is working, but i dont really like the part where i add the owners to the team. I recieve a list of ID's in the .csv file, but i can only add the owners with a mailadres. This would be a easy loop, but there are 3 possible domains that the user is connected to.
My goal is to have a piece of code that adds #domain1.nl to the ID that i get in the .csv, and try to add the user. if i receive a error because that address does not exist, it will try to add the owner with #domain2.nl and #domain3.nl added to it. If nothing works, it should give a Write-Host that says "This domain has to be added"
Below is the piece of code that works, but i think its not the best way to it and it could be improved.
#Adding the owners to the Team
if ($d.ID) {
$Error.Clear()
try {
$ID = $d.ID + "#domain1.nl"
Add-TeamUser -GroupId $GroupID -User $ID -Role Owner
} catch { "Error occured" }
if ($Error) {
$Error.Clear()
try {
$ID = $d.ID + "#domain2.nl"
Add-TeamUser -GroupId $GroupID -User $ID -Role Owner
} catch { "Error occured" }
if ($Error) {
$Error.Clear()
try {
$ID = $d.ID + "#domain3.nl"
Add-TeamUser -GroupId $GroupID -User $ID -Role Owner
} catch { "Error occured" }
if ($Error) {
Write-Host "This domain has to be added to the code"
}
}
}
}
Many thanks in advance!
Use try / catch inside a foreach loop:
$ok = $false
foreach ($domain in '#domain1.nl', '#domain2.nl', '#domain3.nl') {
try {
Add-TeamUser -GroupId $GroupID -User ($d.ID + $domain) -Role Owner
$ok = $true
} catch {
Write-Warning "Error occurred with domain $domain."
}
if ($ok) { break }
}
if (-not $ok) {
Write-Error 'This domain has to be added to the code'
}

How do I delete user in Active Directory through Powershell?

I have to delete users from my AD through Powershell. Powershell has to ask me who I want to delete, once I type in the username it should delete the account. Also when Powershell succesfully deleted the account or it should give me a message.
I'm kind of noob at this, but here is my code:
function aduser-remove($userremove){
Remove-ADUser -Identity $delete
if ($delete -eq $userremove){
return $true
}
else {
return $false
}
}
$delete = Read-host "Which user do you want to delete? (Type in username)."
aduser-remove $delete
if ($userremove -eq $true){
Write-Host $delete "deleted succesfully!" -ForegroundColor Green
}
elseif ($userremove -eq $false){
Write-Host "An error occured by deleting" $delete -ForegroundColor Red
}
else {
Write-Host $delete "does not exist." -ForegroundColor DarkGray
}
The result here is that Powershell does ask if I want to delete the account and it works. But Powershell keeps giving me the else message instead of the if message. Deleting the account was succesfull.
I have no idea what to now or if I'm missing something (I bet I am otherwise it would work).
I hope you guys can help me!
As commented, your code uses variables in places where they do not exist.
Also, I would recommend trying to find the user first and if you do, try and remove it inside a try/catch block, as Remove-ADUser creates no output.
Below a rewrite of your code. Please note that I have changed the name of the function to comply with the Verb-Noun naming convention in PowerShell.
function Remove-User ([string]$userremove) {
# test if we can find a user with that SamAccountName
$user = Get-ADUser -Filter "SamAccountName -eq '$userremove'" -ErrorAction SilentlyContinue
if ($user) {
try {
$user | Remove-ADUser -ErrorAction Stop -WhatIf
return $true
}
catch {
return $false
}
}
# if we get here, the user does not exist; returns $null
}
$delete = Read-host "Which user do you want to delete? (Type in username)."
# call your function and capture the result
$result = Remove-User $delete
if ($result -eq $true){
Write-Host "User $delete deleted succesfully!" -ForegroundColor Green
}
elseif ($result -eq $false){
Write-Host "An error occured while deleting user $delete" -ForegroundColor Red
}
else {
Write-Host "$delete does not exist." -ForegroundColor DarkGray
}
Note also that I have put in the -WhatIf switch. This switch ensures you will only get a message of what would happen. No user is actually deleted. Once you are satisfied the code does what you want, remove the -WhatIf switch.
Hope that helps
If you have rsat installed https://www.microsoft.com/en-us/download/details.aspx?id=45520
remove-aduser https://learn.microsoft.com/en-us/powershell/module/addsadministration/remove-aduser?view=win10-ps

Powershell: How to request user authentication to continue

My Powershell script has some features/functions implemented, but there are some features that I want to restrict to some users.
In order to allow the current user or a different user to select such restricted features from the menu, I am looking for a way to require user authentication from Windows to continue. How could I do that? How the UserAuthentication function below should be like?
Code:
$feature = Read-Host 'Select the feature by typing the number [1 - 2]'
switch ($feature)
{
1
{
write-output "This feature any user can reach"
}
2
{
$user = Read-Host "This feature only some user can reach and requires authentication. Entry your username to proceed"
$allowedUsers = "user1", "user2"
if($allowedUsers.contains($user))
{
write-output "This feature the user $user can reach. Please authenticate to continue"
if((UserAuthentication $user) -eq $true)
{
write-output "$user successfully authenticated"
}
else
{
write-output "$user unsuccessful authenticated"
}
}
else
{
write-output "This feature the user $user cannot reach"
}
}
}
function UserAuthentication($user)
{
return $true #May return 'True' if successfully authenticated or 'False' if not.
}
This answer is for when your users are member of an AD domain
I have changed the function name UserAuthentication to Get-Authentication to comply with the Verb-Noun function naming convention in PowerShell.
# helper function test if a username/password combination is valid.
# if valid, the username entered in the box is returned.
function Get-Authentication {
$Credentials = Get-Credential "$env:USERDOMAIN\$env:USERNAME" -Message "Please authenticate to continue" -ErrorAction SilentlyContinue
if ($Credentials) {
$UserName = $Credentials.UserName
$Password = $Credentials.GetNetworkCredential().Password # --> plain-text password
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ds = New-Object System.DirectoryServices.AccountManagement.PrincipalContext Domain
if ($ds.ValidateCredentials($UserName, $Password)) {
# return the username entered
$UserName
}
}
}
# your code here
# fill in the SamAccountNames of allowed users for this feature
$allowedUsers = 'samaccountname','of', 'users', 'that', 'are', 'allowed', 'to', 'use', 'feature 2'
$feature = Read-Host 'Select the feature by typing the number [1 - 2]'
switch ($feature) {
'1' { Write-Output "This feature any user can reach" }
'2' {
$user = Get-Authentication
if ($null -ne $user -and $allowedUsers -contains $user) {
Write-Output "User $user is allowed for this feature"
}
else {
Write-Output "This feature the user cannot reach"
}
}
}