I am new to powershell Below scripts i have which remove all groups from the user member of tab except "Domain users" this works fine many time without any issues
Removing Groups from User
$list = Import-Csv c:\user\DN.csv
foreach ($entry in $list)
$UserDN = $entry.DistinguishedName
Get-ADGroup -LDAPFilter "(member=$UserDN)" | foreach-object {
if ($_.name -ne "Domain Users") {remove-adgroupmember -identity $_.name -member $UserDN -Confirm:$False}
But the problem is when if this script is not able to remove any group from user member of tab it throws an error below but it doesn't shows from which user id it was unable to remove the membership as the user distinguished name is imported from a CSV file.
Remove-ADGroupMember : The specified account name is not a member of the group
At C:\User\removegroups.ps1:35 char:115
+ Get-ADGroup -LDAPFilter "(member=$UserDN)" | foreach-object {if ($_.name -ne "Domain Users") {remove-adgroupmember <<
<< -identity $_.name -member $UserDN -Confirm:$False}
+ CategoryInfo : NotSpecified: (xyz:ADGroup) [Remove-ADGroupMember], ADException
+ FullyQualifiedErrorId : The specified account name is not a member of the group,Microsoft.ActiveDirectory.Management.Commands.RemoveADGroupMember
$list = Import-Csv c:\user\DN.csv
foreach ($entry in $list)
$UserDN = $entry.DistinguishedName
Get-ADGroup -LDAPFilter "(member=$UserDN)" | foreach-object {
if ($_.name -ne "Domain Users") {
try {
remove-adgroupmember -identity $_.name -member $UserDN -Confirm:$False} }
catch [ADexcption] {
write-output "Error Deleting User:" $_.name
}
}
Import-Csv DN.csv | foreach {
$user = Get-ADUser $_.username
$UserDN = $user.DistinguishedName
Get-ADGroup -LDAPFilter "(member=$UserDN)" | foreach-object {
if ($_.name -ne "Domain Users") {
try {
remove-adgroupmember -identity $_.name -member $UserDN -Confirm:$False
}
catch [ADexcption] {
write-output "Error Deleting User:" $_.name
}
}
}}
Related
I have smtp address beginning with nby keyword like below.
I will remove nby24048#olddomain.com and nby44048#olddomain.com and add nby24048#domainA.com and nby44048#domainA.com. So I will replace those with new domain.
for example :
sAMAccountName,ProxyAddresses
user01,SMTP:user01#domainA.com;smtp:user01#domainA.com;smtp:nby24048#olddomain.com
user02,SMTP:user02#domainA.com;smtp:user02#domainA.com;smtp:nby44048#olddomain.com
....
so on
Here is my script so far:
$Users = import-csv "c:\temp\users.csv"
Foreach ($User in $Users)
{
$Samaccountname = $User.samaccountname
Set-ADUser $samaccountname -Remove #{proxyAddresses=$SMTP}
Set-ADUser $samaccountname -Add #{proxyAddresses=$SMTP}
}
Continuing from my comment, to replace those addresses you can do like below:
$Users = Import-Csv -Path "c:\temp\users.csv"
foreach ($user in $Users) {
$sam = $user.samaccountname
$adUser = Get-ADUser -Filter "SamAccountName -eq '$sam'" -Properties ProxyAddresses
if ($adUser) {
$proxies = $adUser.ProxyAddresses | ForEach-Object {
$_ -replace '^(smtp:nby.+)#olddomain\.com$', '$1#domainA.com'
} | Sort-Object -Unique
# $proxies needs to be a strongly typed string array, so cast to [string[]]
$adUser | Set-ADUser -Replace #{proxyAddresses = [string[]]$proxies}
}
else {
Write-Warning "Could not find user '$sam'.."
}
}
My code:
$searchOU = "OU=a,OU=b,OU=c,OU=d,OU=e,DC=f,DC=g,DC=com"
Get-ADGroup -Filter 'GroupCategory -eq "Security"' -SearchBase $searchOU | sort name | ForEach- Object{
$group = $_
Get-ADGroupMember -Identity $group | Get-ADUser | Where-Object { $_.Enabled -eq $false} | ForEach-Object{
$user = $_
$uname = $user.Name
$gname = $group.Name
Write-Host "Removing $uname from $gname" -Foreground Yellow
Remove-ADGroupMember -Identity $group -Member $user -Confirm:$false #-whatif
}
}
It runs, but it's dog slow. Any suggestions on ways to make it run faster?
You need to remember that Get-ADGroupMember can return users, groups, and computers, not just user objects..
If you want to search for user objects only, you need to add a Where-Object clause there.
Unfortunately, while Get-ADUser has a -Filter parameter that enables you to find disabled users much more quickly than filtering afterwards on the collection of users, using a filter while piping user DN's to it will totally ignore the pipeline and collect all users that are disabled..
So, in this case, we're stuck with appending a Where-Object clause.
You could change your code to rule out all objects from Get-ADGroupMember that are not uders:
$searchOU = "OU=a,OU=b,OU=c,OU=d,OU=e,DC=f,DC=g,DC=com"
Get-ADGroup -Filter "GroupCategory -eq 'Security'" -SearchBase $searchOU | Sort-Object Name | ForEach-Object {
$group = $_
Get-ADGroupMember -Identity $group | Where-Object { $_.objectClass -eq 'user' } |
Get-ADUser | Where-Object { $_.Enabled -eq $false} | ForEach-Object {
Write-Host "Removing $($_.Name) from $($group.Name)" -Foreground Yellow
Remove-ADGroupMember -Identity $group -Member $_ -Confirm:$false #-whatif
}
}
The above removes one disabled user at a time and for each of them writes a line on the console.
You could make it work faster if you can cope with getting a different output on screen like this:
$searchOU = "OU=a,OU=b,OU=c,OU=d,OU=e,DC=f,DC=g,DC=com"
$result = foreach ($group in (Get-ADGroup -Filter "GroupCategory -eq 'Security'" -SearchBase $searchOU)) {
$users = Get-ADGroupMember -Identity $group | Where-Object { $_.objectClass -eq 'user' } |
Get-ADUser | Where-Object { $_.Enabled -eq $false}
if ($users) {
# the Remove-ADGroupMember cmdlet can take an array of users to remove at once
Remove-ADGroupMember -Identity $group -Member $users -Confirm:$false #-whatif
# output an object that gets collected in variable $result
[PsCustomObject]#{Group = $group.Name; RemovedUsers = ($users.Name -join '; ')}
}
}
# if you like, output to console as table
$result | Sort-Object Group | Format-Table -AutoSize -Wrap
# or write to CSV file
$result | Export-Csv -Path 'D:\Test\RemovedUsers.csv' -NoTypeInformation
I want to write script for getting AD Group Membership that is beginning with SSL_VPN for usernames listed in a CSV.
I have tried so far :
Import-Csv C:\Users.csv |
ForEach-Object -pv user { Get-AdUser -filter "displayname -eq '$($_.username)'"} |
Get-ADprincipalGroupMembership |
Select-Object #{ n = 'samaccountname'; e = { $user.samaccountname } }, name |
Export-csv -path C:\UserPermiss.csv -NoTypeInformation
Getting users by their DisplayName property is not the safest thing to do. It would be so much better if your CSV file has other, more unique properties to go by, like SamAccountName, UserPrincipalName, DistinguishedName or EmailAddress..
Anyway, in your loop, you should check if a user with that name can be found and only if so, get the group membership.
Import-Csv 'C:\Users.csv' | ForEach-Object {
$user = Get-ADUser -Filter "DisplayName -eq '$($_.username)'" -Properties DisplayName
if ($user) {
Get-ADprincipalGroupMembership -Identity $user.DistinguishedName |
Where-Object { $_.name -like 'SSL_VPN*' } |
Select-Object #{ Name = 'SamAccountName'; Expression = { $user.SamAccountName } },
#{ Name = 'Group'; Expression = { $_.name }}
}
else {
Write-Warning "User '$($_.username)' not found"
# if you want this message to also appear in your output CSV, do something like this:
[PsCustomObject]#{
'SamAccountName' = "User '$($_.username)' not found"
'Group' = ''
}
}
} | Export-Csv -Path 'C:\UserPermiss.csv' -NoTypeInformation
If you want to see a warning message when the user is not a member of the SSL_VPN group, you can do:
Import-Csv 'C:\Users.csv' | ForEach-Object {
$user = Get-ADUser -Filter "DisplayName -eq '$($_.username)'" -Properties DisplayName
if ($user) {
$group = Get-ADprincipalGroupMembership -Identity $user.DistinguishedName |
Where-Object { $_.name -like 'SSL_VPN*' }
if ($group) {
[PsCustomObject]#{
'SamAccountName' = $user.SamAccountName
'Group' = $group.name
}
}
else {
Write-Warning "User '$($_.username)' is not a member of ssl_vpn group"
}
}
else {
Write-Warning "User '$($_.username)' not found"
}
} | Export-Csv -Path 'C:\UserPermiss.csv' -NoTypeInformation
You can use something like this(frist line of csv must be samaccountname):
$users=Import-Csv D:\adusers.CSV
foreach($user in $users){
$groupname=Get-ADPrincipalGroupMembership -Identity $user.samaccountname |where {$_.name -like "SSL_VPN*"}|select -ExpandProperty name
if($groupname -ne $null){
foreach($group in $groupname){
[string]$data=($user|select -ExpandProperty samaccountname)+';'+$group
$data|Out-File -FilePath d:\stack.csv -Encoding utf8 -Append
}
}
}
$names = Import-CSV C:\PowerShell\TerminatedEmployees.csv
$Date = Get-Date
foreach ($name in $names)
{
Get-ADPrincipalGroupMembership -Identity "$($name.TextBox37)" | select Name | Out-File "C:\Powershell\ADUserMemberships\$($name.TextBox37)Memberships.txt"
$ADgroups = Get-ADPrincipalGroupMembership -Identity "$($name.TextBox37)" | where {$_.Name -ne "Domain Users"}
Remove-ADPrincipalGroupMembership -Identity "$($name.TextBox37)" -MemberOf $ADgroups -Confirm:$false
Disable-ADAccount -Identity "$($name.TextBox37)"
Get-ADUser -Identity "$($name.TextBox37)" | Move-ADObject -TargetPath "OU=DisabledAccounts,OU=XXX,DC=XXX,DC=XXXX,DC=XXX"
Set-ADUser -Identity "$($name.TextBox37)" -Description "Disabled $Date"
}
This is an already working script I have. However, I realized I need to check 2 properties on the AD user to determine if they need to need to go through my foreach statement. Both properties need to be met. If they are then there's no reason for the AD users to be processed.
The AD user is already disabled.
The AD user already resides in the Disabled OU.
I'm thinking this needs to be done in an If -And statement. But does this need to be done before the foreach or inside the foreach?
Start out by retrieving the user account with Get-ADUser and then inspect the Disabled property + compare the Disabled OU to the DistinguishedName of the user:
$names = Import-CSV C:\PowerShell\TerminatedEmployees.csv
$Date = Get-Date
$DisabledOU = "OU=DisabledAccounts,OU=XXX,DC=XXX,DC=XXXX,DC=XXX"
foreach ($name in $names)
{
$ADUser = Get-ADUser -Identity "$($name.TextBox37)"
if(-not($ADUser.Enabled) -and $ADUser.DistinguishedName -like "*,$DisabledOU")
{
# no need to proceed, skip to next name in foreach loop
continue
}
$ADGroups = Get-ADPrincipalGroupMembership -Identity "$($name.TextBox37)"
$ADGroups |Select-Object Name |Out-File "C:\Powershell\ADUserMemberships\$($name.TextBox37)Memberships.txt"
# no need to call Get-ADPrincipalGroupMembership again
$ADgroups = $ADGroups | where {$_.Name -ne "Domain Users"}
Remove-ADPrincipalGroupMembership -Identity "$($name.TextBox37)" -MemberOf $ADgroups -Confirm:$false
Disable-ADAccount -Identity "$($name.TextBox37)"
$ADUser | Move-ADObject -TargetPath $DisabledOU
Set-ADUser -Identity "$($name.TextBox37)" -Description "Disabled $Date"
}
Got the following code, I can created the CSV file of users, but would like it to be only populated by the users that will get deleted from the loop above it. Just not saw how to integrate both together.
Basically, its pulls all users that will get deleted that are 90 days + old, then the users information gets put in to a CSV.
$OU='OU=Users,OU=Test,DC=corporate,DC=domain,DC=com'
$LISTOFACCOUNTS=Get-ADUser -Property lastlogondate -SearchBase $OU -Filter {lastLogonDate -lt $NumberDays}
$LISTOFACCOUNTS | DISABLE-ADACCOUNT -WhatIf
$LISTOFPOTENTIALDELETES=Get-ADUser -SearchBase $OU -Property Lastlogondate -Filter` {lastlogondate -lt $DeleteDate}
FOREACH ($USER in $LISTOFPOTENTIALDELETES) {
IF (($USER.Notes -notlike '*'+$OVERRIDE+'*') -and ($USER.Description -notlike` '*'+$OnLeave+'*'))
{
WRITE-HOST $USER.SamAccountName 'Deleted'
REMOVE-ADOBJECT $USER.SamAccountName -whatif
}
ELSEIF ($USER.Notes -like '*'+$OVERRIDE+'*')
{
WRITE-HOST $USER.SamAccountName 'Not removed due to Administrative Override'
}
ELSE
{
WRITE-HOST $USER.SamAccountName 'Not removed - Presently on Leave'
}
}
$memberOf = #{n='MemberOf';e={ ($_.MemberOf -replace '^CN=([^,]+).+$','$1') -join ';' }}
$LastLogonDays = #{N='Last Logon Days'; E={$($(Get-Date) - ` $([DateTime]::FromFileTime($_.LastLogon))).Days}}
$LastLogon = #{N='LastLogon'; E={[DateTime]::FromFileTime($_.LastLogon)}}
$Mail = #{ Name = 'mail'; Expression = { $_.mail -join ';'; }; }
$Description = #{N='Description'; E={$_.description -join ';'; }; }
Get-ADUser -Filter * -SearchBase $OU -Properties * | Select Enabled, SAMAccountName, ` CanonicalName, Displayname,Givenname, Surname, Department, `
ProfilePath, HomeDrive, $Description, $LastLogonDays, $LastLogon, $mail, $memberOf |
Export-CSV "E:\Temp\_DisabledUserList.csv"
Cheers in advance
Build a list with the user objects before they're deleted:
$deletedUsers = #()
foreach ($USER in $LISTOFPOTENTIALDELETES) {
if ($USER.Notes -notlike ...) {
Write-Host $USER.SamAccountName 'Deleted'
$deletedUsers += $USER
Remove-ADObject $USER.SamAccountName -WhatIf
} else {
...
}
}
and export that list to a CSV:
$deletedUsers | select SamAccountName, ... | Export-Csv 'C:\Temp\deleted.csv'
Side note: I'd recommend using Remove-ADUser instead of Remove-ADObject for removing AD users.