This is my script it can display all the AD group that is assigned to a user account. I just don't know the syntax on how to do a wildcard search.
Write-Host "'Get AD Groups"
$userName = Read-Host -Prompt "Please enter the LDAP ID"
$ADUser = Get-ADUser -Filter "SamAccountName -eq '$userName'" | Select-Object SamAccountName
if($ADUser -eq $null) {
Write-Host "$userName does not exist in AD or account is inactive" -ForegroundColor Red
Continue
} else {
$sourceUser = Get-ADUser -Identity $userName -Properties MemberOf
$sourceGroups = $sourceUser.MemberOf
Foreach($group in $sourceGroups) {
$thisgroup = $group.split(",")[0].split("=")[1]
Write-Host "$thisgroup"
}
}
Related
Trying to create a script that Copies groups from 1 Computer to another. The script also has a list of Groups that won't copy over. I have been able to debug the script until line 42 with the below error message.
Here is my current script:
*If($Hostname -eq 'ISD-TS-01' -or 'ISD-TS-03' -or 'ISD-TS-04')
{
function Show-Menu
{
param (
[String]$Title = 'Copy AD Computer Groups Groups'
)
cls
Write-Host ================ $Title ================
$ComputerToCopy = Read-Host -Prompt 'Input the Computer to copy'
$Computer = $ComputerToCopy
foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -Recursive Select -ExpandProperty SamAccountName
If ($members -contains $Computer) {
Write-Host "$Computer is in $group" -ForegroundColor Red
Pause
Exit
} Else {
Write-Host Starting Script -ForegroundColor Green
}
}
$NewComputer = Read-Host -Prompt 'Input the name of the new computer'
Get-ADComputer -Identity $ComputerToCopy -Properties memberof -Verbose | Select-Object -ExpandProperty memberof -Verbose |
Add-ADGroupMember -Members $NewComputer -PassThru -Verbose
$Computer = $NewComputer
$groups = 'G-SCCM-SD-EGRESS_WIN10'
foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty SamAccountName
If ($members -contains $Computer) {
#remove-adgroupmember -Identity "$Group" -Member "$NewComputer" -Confirm:$false
Write-Host "$Computer has been removed from $group" -ForegroundColor Cyan
} Else {
Write-Host "$Computer is not a member of $group" -ForegroundColor Green
}
}
Write-Host "1: Press '1' to Retry."
Write-Host "Q: Press 'Q' to quit."
}
do
{
show-menu
$input = Read-Host "Select an option"
Switch ($input)
{
'1' {
cls
'You chose option #1'
}'2'{
cls
'You chose option #2'
}'q'{
return
}
}
pause
}
until ($input -eq 'q')
}
Else {
Write-Host "Script Cannot be Run on this Host. Please use TS-01"
Read-Host
}*
Powershell Error
You have to use the SamAccountName of the station! the SamAccountName is the computer name with $ at the end
you can use this in your script to find it
Get-ADComputer -Identity $NewComputer | Select-Object -ExpandProperty SamAccountName
I would like to check the input option is allow 1-3 number ONLY, and input other numbers and characters will show the warning message, how to do that?
Can I check the input user account [value] from AD user is whether exist or not on Powershell? If the record not exist, just return the warning message.
Please help. Thanks!
import-module ActiveDirectory
import-module C:\PS\color_menu.psm1
CreateMenu -Title "AD User Account Expire Tools" -MenuItems "View the User Account Expire Date","Set the User Account Expire Date","Exit" -TitleColor Red -LineColor Cyan -menuItemColor Yellow
do {
[int]$userMenuChoice = 0
while ( $userMenuChoice -lt 1 -or $userMenuChoice -gt 3) {
Write-Host "1. View the User Account Expire Date"
Write-Host "2. Set the User Account Expire Date"
Write-Host "3. Exit"
[int]$userMenuChoice = Read-Host "Please choose an option"
switch ($userMenuChoice) {
1{$useraccount = Read-Host -prompt "Please input an user account"
Get-ADUser -Identity $useraccount -Properties AccountExpirationDate | Select-Object -Property SamAccountName, Name, AccountExpirationDate
Write-Host "";
Write-Host "";
}
2{$useraccount = Read-Host -prompt "Please input an user account"
do {
$expiredatetimeStr = Read-Host -prompt "Please input the user expiration date and time (DateFormat: MM/dd/yyyy) or just press Enter to make the account non-expiring"
if ($expiredatetime = $expiredatetimeStr -as [datetime]) {
Set-ADAccountExpiration -Identity $useraccount -DateTime $expiredatetime
Get-ADUser -Identity $useraccount -Properties AccountExpirationDate | Select-Object -Property SamAccountName, Name, AccountExpirationDate
Write-Host "";
Write-Host "";
}
elseif ($expiredatetimeStr.Trim() -eq '') {
Clear-ADAccountExpiration -Identity $useraccount
Get-ADUser -Identity $useraccount -Properties AccountExpirationDate | Select-Object -Property SamAccountName, Name, AccountExpirationDate
Write-Host "";
Write-Host "";
}
else {
Write-Warning 'Please enter a valid date.'
continue
}
break
} while ($true)
}
3{Write-Host "Exit";Exit
}
default {Write-Host "Incorrect input" -ForegroundColor Red
Write-Host "";
Write-Host "";
}
}
}
} while ( $userMenuChoice -ne 3 )
The problem is that you are directly casting a user input to an int:
$a = [int] Read-Host
What if the return value of Read-Host isn't an int?
The solution is to just accept whatever Read-Host gives you, and check the value after, e.g:
$a = Read-Host
try {
$intVal = [Convert]::ToInt32($a, 10)
... etc ...
}
catch {
... etc ...
}
Working on an HR project at work to handle user terminations with PS code. Current challenge is to:
1. Test the user account if enabled/disabled.
2. If Disabled, test their manager's SAMAccount if enabled/disabled.
3. Repeat until an account is found enabled
4. Return that account's SAMAccount.
Working code thus far:
$testuser = "johndoe"
If ($(get-aduser $testuser).enabled -eq $true{
$usermgr1 = get-aduser $testuser -properties * | select #{Name='Manager';Expression={(Get-ADUser $_.Manager).SAMAccountName}}
}
The output of the above is formatted as below. I definitely don't want the header either.
Manager
------
JaneDoe
I then tried to expand this to the first test, seeing if the manager's account is enabled or not:
If ($get-aduser $usermgr1).enabled -eq $true) | select #{Name='Manager';Expression={(Get-ADUser $_.Manager).SAMAccountName}}
Else Write-Host "Manager Account Disabled"
}
This attempt returns an error:
Get-ADUser : Cannot validate argument on parameter 'Identity'. The Identity property on the argument is null or empty.
At line:4 char:18
+ If ($(get-aduser $usermgr1).enabled -eq $true){write-host "Enabled"}
The expected output here is the SAMAccount of this user's manager if enabled; if disabled, I would continue adding more levels to the code up to four or five. I don't yet know enough powershell to loop back and re-test dynamically in order to avoid hardcoding it.
-EDIT-
Using itchydon's example, I opted to limit the recursion at two levels above the target user. The probability of three or more levels all being disabled simultaneously is low. Therefore the working code is:
$testuser = "janedoe"
$user = get-aduser $testuser -properties manager
if ($user.enabled -eq $false){
$usermgr1 = get-aduser $user.manager
if ($usermgr1.enabled -eq $true){Write-Host $usermgr1.SamAccountName}
else{
$user1 = get-aduser $usermgr1 -properties manager
if ($user1.enabled -eq $false){
$usermgr2 = get-aduser $user1.manager
if ($usermgr2.enabled -eq $true){
Write-Host $usermgr2.SamAccountName}
else{Write-Host "Recursion cannot complete. Handle manually."}
}
}
}
-EDIT-
Now with the working code, trying to set mailbox properties with the same logic. What I'm noticing is the set-mailbox command is executing on the first test, regardless if the manager is disabled or not:
if ($user.enabled -eq $false){
$usermgr1 = get-aduser $user.manager
if ($usermgr1.enabled -eq $true){
$mgr1 = $usermgr1.SamAccountName
$mgr1email = get-aduser $mgr1 -properties EmailAddress
$mgr1email.emailaddress
}
Set-Mailbox $testuser -ForwardingAddress $mgr1email.EmailAddress -DeliverToMailboxAndForward $False
Set-MailboxAutoReplyConfiguration -identity $testuser -AutoReplyState Enabled -InternalMessage $internal -ExternalMessage $external
Write-Host $testuser "Completed"
}
else{
In this case, the test whether $usermgr1.enabled -eq $true fails, and I would expect the set-mailbox commands to be skipped entirely, moving on to the else{ statement.
I thought it was just a matter of moving the commands inside the test declaration like so:
if ($user.enabled -eq $false){
$usermgr1 = get-aduser $user.manager
if ($usermgr1.enabled -eq $true){
$mgr1 = $usermgr1.SamAccountName
$mgr1email = get-aduser $mgr1 -properties EmailAddress
$mgr1email.emailaddress
Set-Mailbox $testuser -ForwardingAddress $mgr1email.EmailAddress -DeliverToMailboxAndForward $False
Set-MailboxAutoReplyConfiguration -identity $testuser -AutoReplyState Enabled -InternalMessage $internal -ExternalMessage $external
Write-Host $testuser "Completed"
}
}
else{
However, the end result of that when the enabled test passes is that the set-mailbox commands are skipped entirely, and no action is taken at all.
-EDIT-
Fixed the mailbox commands problem by leaving variable declarations in their own block like so:
$user = get-aduser $testuser -properties manager
if ($user.enabled -eq $false){
$usermgr1 = get-aduser $user.manager
$mgr1 = $usermgr1.SamAccountName
$mgr1email = get-aduser $mgr1 -properties EmailAddress}
if ($usermgr1.enabled -eq $true){
Set-Mailbox $testuser -ForwardingAddress $mgr1email.EmailAddress -DeliverToMailboxAndForward $False
Set-MailboxAutoReplyConfiguration -identity $testuser -AutoReplyState Enabled -InternalMessage $internal -ExternalMessage $external
Write-Host $testuser "Completed"
}
I am unable to test this unfortunately but I think this is what you are after.
$testuser = "johndoe"
$user = get-aduser $testuser -properties manager
if ($user.enabled -eq $true){
$usermgr1 = get-aduser $user.manager
if ($usermgr1.enabled -eq $false){
Write-Host "Manager Account Disabled"
}
else{
write-host $usermgr1.samaccountname
}
}
In the above rather than keep doing a get-aduser we do it once for the testuser and save it to a variable ($user). We can then access each property of the object - so we use this to check the enabled status as shown e.g. $user.enabled -eq $true. If true - do another get-aduser for the manager's information using the same technique
I have created a script for a project with some code which I was given fused with my own. Most of the commands which are great, but unfortunately two commands are not working.
These commands are:
Set-ADUser $UserName -replace #{title="Former Employee" + $title}
Move-ADObject -Identity $UserName -TargetPath "OU=Former Employee,OU=Users,OU=Contoso,DC=Contoso,DC=local"
Any ideas? I appreciate the help!
Here is the full script:
$UserName = Read-Host "Please enter username to be disabled"
if ($UserName) {
''
} Else {
'User not Found'
}
Disable-ADAccount $UserName
Get-ADUser $UserName -Properties MemberOf | ForEach-Object {
$_.MemberOf | Remove-ADGroupMember -Members $_.DistinguishedName -Confirm:$false }
$title = get-aduser $UserName -properties title
$title = $title.title
$old=Get-ADuser $UserName -properties Description
$old = $old.description
$new = "DISABLED " + $old
set-aduser $UserName -description $new
set-aduser $UserName -clear "manager"
set-aduser $UserName -clear "telephonenumber"
# these two:
set-aduser $UserName -replace #{title="Former Employee" + $title}
Move-ADObject -Identity $UserName -TargetPath "OU=Former Employee,OU=Users,OU=Contoso,DC=Contoso,DC=local"
I think it's better to clear up a bit of your code. Have a look at this:
$SamAccountName = Read-Host 'Please enter the SamAccountName of the user you want to disable'
$VerbosePreference = 'SilentlyContinue'
$VerbosePreference = 'Continue'
Try {
$ADUser = Get-ADUser -Identity $SamAccountName -Properties MemberOf, Title, Description
Write-Verbose "User '$($ADUser.Name)' found in AD"
}
Catch {
throw "No user found in AD with SamAccountName '$SamAccountName'"
}
Write-Verbose 'Disable user'
Disable-ADAccount $ADUser
foreach ($Group in $ADUser.MemberOf) {
Write-Verbose "Remove user from group '$Group'"
Remove-ADGroupMember -Identity $Group -Members $ADUser -Confirm:$false
}
$NewTitle = "Former Employee {0}" -f $ADUser.Title
Write-Verbose "Set 'Title' to '$NewTitle'"
Set-ADUser -Identity $ADUser -Title $NewTitle
$NewDescription = "DISABLED {0}" -f $ADUser.Description
Write-Verbose "Set 'Description' to '$NewDescription'"
Set-ADUser -Identity $ADUser -Description $NewDescription
foreach ($Property in #('Manager', 'telephonenumber')) {
Write-Verbose "Clear property '$_'"
Set-ADUser -Identity $ADUser -Clear $Property
}
$NewTargetPath = "OU=Former Employee,OU=Users,OU=Contoso,DC=Contoso,DC=local"
Write-Verbose "Move AD User to '$NewTargetPath'"
Move-ADObject -Identity $ADUser -TargetPath $NewTargetPath
Some tips:
Use Write-Verbose to show what is happening in the script. Yuo can disable/enable this by commenting out the VerbosePreference.
Always start with retrieving an object instead of working with text strings ($UserName vs $ADUser). See Get-ADUser as the very first action.
Work with Try/Catch in case things fail.
Always use the parameter names. It makes it more clear on what you're trying to do.
I am writing a powershell script to disable users due to the fact that we get a list of them everyday and it is monotonous. I paste the list from the ticket into a csv formatted as Lastname, Firstname then run my script with imports the list, serches ad and ask if you want to disable if it finds them. Here is the code...
# Set variables
$Import = "C:\Scripts\Support Files\Users_To_Disable.csv"
$Export = "C:\Scripts\Support Files\Disabled_Users_Output.txt"
# Import user list
$Users = Import-CSV $Import
foreach ($User in $Users)
{
# Set user variables
$LastName = $User.("Surname")
$FirstName = $User.("GivenName")
# Use user variables from list to search ad
$UserName = (Get-ADUser -Filter "GivenName -like '$FirstName*' -and Surname -like '$LastName*'").SamAccountName
# What to do if it finds nothing
If ($UserName -eq $Null)
{
Write-Host $LastName, $FirstName NA -ForegroundColor Yellow
Write-Output "$LastName, $FirstName NA" | Out-File $Export -Append
}
# What to do if it finds a user
Else
{
# Ask for user input
Write-Host $LastName, $FirstName Found -ForegroundColor Green
Write-Host UserName = $UserName -ForegroundColor Green
DO {
$Disable = Read-Host "Do you want to disable user? (Y/N)"
If($Disable -eq "Y")
{
# Disable the user
Disable-ADAccount -Identity $UserName
# Move the user
Get-ADUser $UserName | Move-ADObject -TargetPath "OU=Disabled - Retention,DC=intranet,DC=sw"
# Add Disabled Users group
Add-ADGroupMember "Disabled Users" -Members "$UserName"
# Set Disable Users as primary group
$Group = Get-ADGroup "Disabled Users" -Properties #("PrimaryGroupToken")
Get-ADUser "$UserName" | Set-ADUser -Replace #{PrimaryGroupID=$Group.PrimaryGroupToken}
# Remove all other groups
$User = Get-ADUser "$UserName" -Properties MemberOf
$Groups = $User.MemberOf |ForEach-Object { Get-ADGroup $_ }
$Groups | ForEach-Object { Remove-ADGroupMember -Identity $_ -Members $User -Confirm:$false }
# Output
Write-Host $LastName, $FirstName Disabled -ForegroundColor Red
Write-Output "$LastName, $FirstName Disabled" | Out-File $Export -Append
Break
}
}
Until ($Disable -eq "N")
}
}
Invoke-Item $Export
All of that works, what is scary is that if there are blank cells above a user then it returns all of the users in ad and asks if you want to disable all of them. In other words if the csv looks like this...
Surname GivenName
User Test
Everything works fine, but if it looks like this...
Surname GivenName
User Test
Pandemonium, well not really but it does ask if you want to initiate a resume generating event, which I don't so how can I build in some safety that would stop it from returning all of ad when there are blanks in the csv before users?
You can eliminate the blank lines by filtering out Null values on your import, which should resolve the problem.
$Users = Import-CSV $Import | Where-Object {$_.Surname}