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>
Related
I have a powershell script that uses a menu and a selection. So loops until selection is 0. For one selection it tests entered port with "Test-NetConnection". But for some reason after this is ran, whenever another selection is made it seems "Test-NetConnection" is always ran, the banner shows up in powershell (even though it is very quick, but it shouldn't be executed.
I removed some selections. And I also have a few custom functions. But not sure why this is happening. Any help would be greatly appreciated!
Powershell...
while ($selection -ne 0) {
Write-Output ""
Write-Output "__MENU__"
Write-Output "0. Exit"
Write-Output "1. Set Target Machines"
Write-Output "2. Set Save Directory"
Write-Output "4. Save MSINFO32"
Write-Output "5. Save All Installed Software"
Write-Output "9. Save GPO Info (gpresult)
Write-Output "10. Test WMI"
Write-Output "11. Test TCP Port"
Write-Output "14. Test Syslog"
Write-Output ""
Write-Output "Target Machines: $($targetComputers -Join ',')"
Write-Output "Save Directory: $savePath`n"
$selection = Read-Host -Prompt "Selection"
Write-Output ""
switch ($selection) {
0 { break }
1 { ... }
2 { ... }
11 {
$testPort = Read-Host -Prompt "TCP Port to Test (Leave blank for default: 80)"
Write-Output ""
if (($testPort -eq $null) -Or ($testPort -eq "")) { $testPort = 80 }
foreach ($computer in $targetComputers) {
try {
$netcon = Test-NetConnection -ComputerName $computer -Port $testPort -ErrorAction "Stop"
if($netcon.TcpTestSucceeded) { Write-Output "TCP Port $testPort test was successful on $computer." }
else { Write-Warning "TCP Port $testPort test was unsuccessful on $computer." }
}
catch { Write-Warning "TCP Port $testPort test was unsuccessful on $computer." }
}
} #11
14 {
$sysServer = Read-Host -Prompt "Syslog Server (Leave blank for default: ${env:computername})"
$sysProto = Read-Host -Prompt "Syslog Server Protocol (Leave blank for default: TCP)"
$sysPort = Read-Host -Prompt "Syslog Server Port (Leave blank for default: 514)"
Write-Output ""
if (($sysServer -eq $null) -Or ($sysServer -eq "")) { $sysServer = $env:computername }
if (($sysProto -eq $null) -Or ($sysProto -eq "")) { $sysProto = "TCP" }
if (($sysPort -eq $null) -Or ($sysPort -eq "")) { $sysPort = 514 }
sendSyslog -Server $sysServer -Protocol $sysProto -Port $sysPort
} #14
default { break }
} #switch
} #while
Your menu option "9. Save GPO Info (gpresult) is missing a closing quote.
Make this easier for yourself and use a Here-String for the menu:
$menu = #"
__MENU__
0. Exit
1. Set Target Machines
2. Set Save Directory
4. Save MSINFO32
5. Save All Installed Software
9. Save GPO Info (gpresult)
10. Test WMI
11. Test TCP Port
14. Test Syslog
"#
Then instead of looping like while ($selection -ne 0), run an endless loop you can exit as soon as the user types a '0'.
# enter an endless loop here.
# exit that loop right after the Read-Host when the user type '0'
while ($true) {
Write-Host $menu
# some in-between code.. #
$selection = Read-Host -Prompt "Selection"
if ($selection -eq '0') { break } # or exit if you want to stop the entire script here
# rest of your code.. #
}
P.S. anything coming back from Read-Host is a string, not a number.
I wrote out a PowerShell Script to rename my computer, add it to specific OU's and join it to the domain. My question is we have two types of computer Desktop (DT) and Laptop (LT) and we give it an asset tag and I would like for it to ask me to select if it is a desktop or laptop and then ask for the asset tag number and then add the DT or LT in front of the asset tag number as the computer name (sorry if confused) example: DT01234 or LT01235. I will post my code below and bold the area that renames the computer. Any and all help would be greatly appreciated.
Write-Host "Select Desktop or Laptop [1-2] [Default 1]:
1. Desktop
2. Laptop"
$computertype = Read-Host
Write-Host "Please Enter Asset Tag"
$NewCompName = Read-Host
$renamecomputer = $true
if ($NewCompName -eq "" -or $NewCompName -eq $env:COMPUTERNAME) {$NewCompName = $env:COMPUTERNAME; $renamecomputer = $false}
Write-Host "Please enter your desired location [1-7] [Default 1]:
1. Test
2. Compliance Stations
3. Controls Stations
4. Processing Stations
5. QC Stations
6. Receiving Stations
7. Shipping Stations"
$ou = Read-Host
#$creds = Get-Credential
function Test-ADCrential{
[CmdletBinding()]
param(
[pscredential]$Credential
)
try {
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
if(!$Credential) {
$Credential = Get-Credential -EA Stop
}
if($Credential.username.split("\").count -ne 2) {
throw "You haven't entered credentials in DOMAIN\USERNAME format. Given value : $($Credential.Username)"
}
$DomainName = $Credential.username.Split("\")[0]
$UserName = $Credential.username.Split("\")[1]
$Password = $Credential.GetNetworkCredential().Password
$PC = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Domain, $DomainName)
if($PC.ValidateCredentials($UserName,$Password)) {
Write-Verbose "Credential validation successful for $($Credential.Username)"
return $True
} else {
throw "Credential validation failed for $($Credential.Username)"
}
} catch {
Write-Verbose "Error occurred while performing credential validation. $_"
return $False
}
}
$mycreds = Get-Credential
Write-Host "Adding $NewCompName to the domain"
Read-Host "Press enter to change computer name"
if ($renamecomputer -eq $true)
{Rename-Computer -NewName $NewCompName -DomainCredential $mycreds}
Read-Host "Press enter to restart computer"
Restart-Computer
Looks like you want something like this
if ($NewCompName -eq "" -or $NewCompName -eq $env:COMPUTERNAME)
{
$NewCompName = $env:COMPUTERNAME; $renamecomputer = $false
}
elseif($NewCompName -inotmatch "^DT|^LT")
{
switch($computertype )
{
1{$NewCompNamePrefix = "DT"}
2{$NewCompNamePrefix = "LT"}
default{}
}
$NewCompName = $NewCompNamePrefix + $NewCompName
}
the -inotmatch is just making sure that if a $newcompname is inputted that already looks like DTwhatever or LTwhatever, it won't append an extra LT or DT
Unrelated (just me being a bit nitpicky):
Look into Read-host -Prompt and nest the prompts into do while loops, so you can validate that the input is what you're expecting.
something like this
$properChoices = #("a","b","c")
do
{
$choice = (Read-Host -Prompt "pick a, b, or c").ToLower()
switch($choice)
{
"a"{"You picked $choice"}
"b"{"You picked $choice"}
"c"{"You picked $choice"}
default{Write-Warning "Invalid Input"}
}
}
while($choice -notin $properChoices)
I'm wondering how to re-prompt if someone typos or enters something other than yes/no
Would it have to be a created as a prompting function or is there an easier way?
$Continue = Read-Host -Prompt "Continue? Yes/No"
Switch($Continue){
'Yes' { Write-host -ForegroundColor Yellow "Moving on..." }
'No' {Write-host "...GoodBye"
Exit
}
default { #HOW TO RE-PROMPT USER FOR YES/No?
}
}
Using a While loop which a check variable. If Yes is typed then $Check will equal $true exiting the loop. Else it will stay false and rerun the loop again.
$Check = $false
while($Check -eq $false){
Switch(Read-Host -Prompt "Continue? Yes/No"){
'Yes' {
Write-host -ForegroundColor Yellow "Moving on..."
$Check = $true
}
'No' {
Write-host "...GoodBye"
return
}
}
}
I am writing a powershell script to manage our local administrator accounts using a csv file.
#variable to store the data in data.csv
$userobjects = Import-CSV C:-data.csv
function main-list{
Write-Host "--------------------------------------"
Write-Host "Windows Powershell Account Manager"
Write-Host "--------------------------------------"
Write-Host "1 - Change Name"
Write-Host "2 - Disabled Account"
Write-Host "3 - Delete User"
Write-Host "4 - Exit"
[int]$action = Read-Host "Enter the menu number from above"
if ($action -eq 1){change-name}
if ($action -eq 2){disable-account}
if ($action -eq 3){delete-user}
if ($action -eq 4){cls; break}
}
function change-name
{
foreach ($user in $userobjects)
{
#Assign the content to variables
$FileHostname = $user.Host
$FileAccount = $user.Account
$FileNewname = $user.Rename
$FileDisable = $user.Disable
$FileDelete = $user.Delete
# Rename
if (($user.Account -ne $user.Rename) -and ($user.Rename -ne '' ))
{
#Write-Host "old name :"$FileHostname"/"$FileAccount "-> new name :"$FileHostname"/"$FileNewname
$connection = $FileHostname+"/"+$FileAccount
$accName = [ADSI]("WinNT://$connection")
if ($accName.path -eq "WinNT://"+$connection+"")
{
$accName.psbase.Rename($FileNewname)
Write-Host "Account(s) renamed"
$user.Account = $user.Rename
}
else
{
Write-Host "Account name :"$connection "can't be found on the host"
}
$user.Account = $user.Rename
$userobjects | export-csv C:-data.csv -notype
}
}
Write-Host "--------------------------------------"
main-list
}
function disable-account
{
foreach ($user in $userobjects)
{
#Assign the content to variables
$FileHostname = $user.Host
$FileAccount = $user.Account
$FileNewname = $user.Rename
$FileDisable = $user.Disable
$FileDelete = $user.Delete
if ($user.Disable -eq 'yes')
{
$connection = $FileHostname+"/"+$FileAccount
$accName = [ADSI]("WinNT://"+$connection+"")
if ($accName.UserFlags -eq '515')
{
Write-Host "Account :"$connection "is already disabled"
}
else
{
$accName.description = "Account disabled"
$accName.UserFlags = 2
$accName.setinfo()
Write-Host "Account(s) disabled"$connection
}
}
}
Write-Host "--------------------------------------"
main-list
}
function delete-user
{
foreach ($user in $userobjects)
{
#Assign the content to variables
$FileHostname = $user.Host
$FileAccount = $user.Account
$FileNewname = $user.Rename
$FileDisable = $user.Disable
$FileDelete = $user.Delete
#Delete
if ($user.Delete -eq 'yes')
{
$connection = $FileHostname+"/"+$FileAccount
$accName = [ADSI]("WinNT://"+$connection+"")
$accName.delete("user",$accName.name)
#Write-Host $connection deleted
}
else
{
Write-Host "Account name :"$connection "can't be found on the host"
}
}
}
}
$userobjects | export-csv C:-\data.csv -notype
main-list
I don't really know why I have this message when I am trying to use the delete function : "Unknown name", it is like it doesn't find the local account to delete it but I am not sure. However, It works perfectly when I want to rename or disable accounts.
My data file looks like that
http://www.noelshack.com/2016-05-1454622367-capture.png
I will post the real message when I will be back to work tomorow.
Thank you for your help.
Quick skim... wouldn't this need to be used instead? I think your $accName.name would be using the machine name.
$accName.delete("user",$user.account)
You delete() the user from the computer, so your [adsi] object should bind to the computer and call Delete() on that instead:
# Just the machine name, nothing more:
$Machine = [ADSI]"WinNT://$FileHostname"
# Now delete the user account from the machine
$Machine.Delete('user',$FileAccount)
I'm trying to create a script that creates a unique user I Active Directory.
Before the script can create a user it needs to make sure the username is available by asking two different domains if the generated username exists. The problem is I don't how generate a new username or rerun part of the script if necessary. Lets say that if the generated username exists in one of the domains I wan't to generate a new username and try again with the new one. This is what I have so far.
Import-Module ActiveDirectory
$firstname = "Test"
$lastname = "Tester"
$SecondaryDomain = "server1.domain1.net"
$PrimaryDomain = "server2.domain2.net"
$ErrorActionPreference = "SilentlyContinue"
$Generate = [Char[]]"$firstname$lastname"
$Generatedusername = ($Generate | Get-random -Count 3) -join ""
Write-host $Generatedusername
if (Get-ADUser -Filter {SamAccountName -eq $Generatedusername} -Server $PrimaryDomain)
{
#If the variable equals 1 the user exists
$PrimaryDomainOK = "1"
}
else
{
$PrimaryDomainOK = "0"
}
if (Get-ADUser -Filter {SamAccountName -eq $Generatedusername} -Server $SecondaryDomain)
{
#If the variable equals 1 the user exists
$SecondaryDomainOK = "1"
}
else
{
$SecondaryDomainOK = "0"
}
Write-host "Primary Domain $PrimaryDomainOK"
Write-host "Secondary Domain $SecondaryDomainOK"
If ($PrimaryDomainOK -and $SecondaryDomainOK -eq 0)
{
Write-host "Creating Account"
}
Else
{
Write-host "Can't create account"
}
Add a while statement embracing your generation/verification which checks for the status of $PrimaryDomainOK and $SecondaryDomainOK.
...
$Generate = [Char[]]"$firstname$lastname"
while(($PrimaryDomainOK -ne 0) -and ($SecondaryDomainOK -ne 0)) {
$Generatedusername = ($Generate | Get-random -Count 3) -join ""
Write-host $Generatedusername
...
...
...
If ($PrimaryDomainOK -and $SecondaryDomainOK -eq 0)
{
Write-host "Creating Account"
}
Else
{
Write-host "Can't create account"
}
}
Remember the closing brace.