Below embedded foreach commands needs $user to come from list.txt, dump groups from AD into $user.txt file and remove.
How do I specify $user as each line in the list.txt whild also verifying the formatting of the list inside the list.txt is just one name per line, no comma?
foreach ($user in .\list.txt) {
$groups = (Get-ADUser $user -Properties MemberOf).MemberOf
Add-Content -Path C:\TEMP\RemoveGroups\$user.txt -Value $groups
foreach ($group in $groups) {
Remove-ADGroupMember $group -Member $user
}
$List = Get-Content .\List.txt
Foreach ($User in $List){
$Groups = (Get-ADUser $user -Properties MemberOf).MemberOf
Foreach ($GroupDN in $Groups){
Try {
$Group = Get-ADGroup $GroupDN
Remove-ADGroupMember $Group -member $user -ErrorAction Stop
$Succeed = $Succeed,$Group.Name -join ";"
}
Catch {
$Failed = $Failed,$Group.Name -Join ";"
}
}
$temp = New-Object psobject -ArgumentList #{
User = $User
Succeed = $Succeed
Failed = $Failed
}
Export-Csv -InputObject $temp -Path C:\TEMP\RemoveGroups\Result.csv -Encoding UTF8 -NoTypeInformation -Append
}
You will get the CSV file like this:
User,Succeed,Failed
user1,Group1;Group2,Group3;Group4
user2,Group2;Group3,Group1;Group4
You can use the following code.
# Read the list of users to an array of strings.
$users = Get-Content .\list.txt
foreach ($user in $users) {
# Validate that the username only contains a-z and 0-9.
if ($user -match "^[a-zA-Z0-9]+$") {
$groups = (Get-ADUser $user -Properties MemberOf).MemberOf
Add-Content -Path C:\TEMP\RemoveGroups\$user.txt -Value $groups
foreach ($group in $groups) {
Remove-ADGroupMember $group -member $user
}
}
}
Related
I'm looking to export users with their groups in Active Directory through powershell, but I can't seem to get the pipe to work for some reason the powershell script I'm using right now is
`
$groups = get-adgroup -filter *
foreach ($group in $groups) {
$naam = $group.name
$members = Get-ADGroupMember -identity $group
write-host “Group: $naam”
write-host “————————————-”
foreach ($member in $members) {
$memnaam = $member.samaccountname
write-host “$naammem”
}`
I just can't seem to figure this out any recommendations?
`
$groups = get-adgroup -filter *
foreach ($group in $groups) {
$naam = $group.name
$members = Get-ADGroupMember -identity $group
write-host “Group: $naam”
write-host “————————————-”
foreach ($member in $members) {
$memnaam = $member.samaccountname
write-host “$naammem”
} | Export-CSV c:\FileName.csv`
Check for typos in variable names (you have one) and that you've closed all parentheses and braces. Even better, don't use variables where not needed:
$groups = get-adgroup -Filter *
# If you save your search as an object you won't need to re-run it multiple times to use the data
Write-Host "Processing groups"
$SearchResult = $Groups | ForEach-Object {
$GroupName = $_.Name
# Some simple error trapping
Try {
# Writing to host for informational only
Write-Host "$GroupName..." -NoNewline
$Members = (Get-ADGroupMember -Identity $_ -ErrorAction Stop).SamAccountName
}
Catch {
$Members = $_
}
# Output results as an object
[pscustomobject]#{
Group = $GroupName
Members = $Members
}
Write-Host "Done"
}
Write-Host "Processing complete"
# If you want to display it in console
$SearchResult | Format-List
# Or a GridView
$SearchResult | Out-GridView
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'.."
}
}
Im trying to run the below code that compares the user and group and confirms if the user is a member of the group. But i'm unable to export the output to an excel.
$users = gc .\UserInfo.csv
$groups = gc .\groupInfo.csv
$outputFilePath = "C:\Users\salesid.csv"
$members = foreach ($group in $groups) {Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty SamAccountName
foreach ($user in $users) {
If ($members -contains $user) {
$a = write-host "$user is a member of $group"
} Else {
$a = Write-Host "$user is not a member of $group"
}
}
}
$a| Export-Csv .\Output.csv -NoTypeInformation
Read-Host -Prompt "Press Enter to exit"
To output as CSV file you can open in Excel, you need to output objects in the loop, not strings:
$users = Get-Content .\UserInfo.csv
$groups = Get-Content .\groupInfo.csv
$outputFilePath = "C:\Users\salesid.csv"
# loop through the groups; collect all output in $result
$result = foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -Recursive | Select-Object -ExpandProperty SamAccountName
# loop through the users array and outout objects that get collected in variable $result
foreach ($user in $users) {
[PsCustomObject]#{
Group = $group
User = $user
IsMember = ($members -contains $user) # True or False in the output
}
}
}
$result | Export-Csv -Path $outputFilePath -UseCulture -NoTypeInformation
If the amount of data is too large to handle in memory, the following code should work, BUT will be slower because of all the extra disk-write actions:
# loop through the groups
foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -Recursive | Select-Object -ExpandProperty SamAccountName -Unique
# loop through the users array and outout objects that get collected in variable $result
foreach ($user in $users) {
$isMember = "$user is {0}a member of $group" -f $(if ($members -contains $user) {''} else {'NOT '})
[PsCustomObject]#{
Group = $group
User = $user
IsMember = $isMember
} | Export-Csv -Path $outputFilePath -UseCulture -Append -NoTypeInformation
}
}
switch -UseCulture makes sure the delimiter character is the same your local Excel will understand. This might be the default comma, but perhaps your system uses the semi-colon as list seoarator
File.csv contains a list of groups that are in different domains. I'm trying to recursively pull the list of users in the list but it keeps giving me the following at at $adgroup:"No positional parameter found"
$groups = Get-Content -path 'C:\Temp\file.csv'
$result = foreach ($group in $groups)
{
foreach ($domain in $domains)
{
$adGroup = Get-ADGroup $group -Searchbase "" -server thegc:3268
$x = ($x.DistinguishedName -split ',DC=')[1]
$members = (Get-ADGroupMember $adGroup -Server $x -recursive).where({
$_.ObjectClass -eq 'User'
})
foreach($user in $members)
{
[pscustomobject]#{
GroupName = $adGroup.Name
samAccountName = $user.samAccountName
distinguishedName = $user.distinguishedName
name = $user.name
}
}
}
}
$result | Export-Csv c:\temp\output.csv -NoTypeInformation
Any help would be appreciated here-
The below PowerShell script iterates through the groups listed in the test.csv file.
It pulls samAccountName and distinguishedName from each user in the various groups. However, when I try to pull groupName the output is "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection". Not sure how to fix this-
$groups = Get-Content test.csv
$domains = (Get-ADForest).Domains
foreach ($group in $groups)
{
foreach ($domain in $domains)
{
if (Get-ADGroup $group -Server $domain)
{
Get-ADGroupMember $group -Server $domain | select groupName, samAccountName, distinguishedName | Export-Csv c:\temp\file.csv -notypeinformation -append
}
}
}
I have tried the below, but it just outputs an empty column instead:
$groups = Get-Content test.csv
$domains = (Get-ADForest).Domains
foreach ($group in $groups)
{
foreach ($domain in $domains)
{
if (Get-ADGroup $group -Server $domain)
{
Get-ADGroupMember $group -Server $domain | select samAccountName, distinguishedName |
Get-ADUser #{name = ‘MemberOf’;’expression={$_.MemberOf -join “;”}} |
Export-Csv c:\temp\file.csv -notypeinformation
}
}
}
Try this, I added some optimization to your code :)
Note, try {...} catch {...} is more or less needed here because both cmdlets Get-ADGroup and Get-ADGroupMember will throw if the object is not found.
$ErrorActionPreference = 'Stop'
$groups = Get-Content test.csv
$domains = (Get-ADForest).Domains
$result = foreach ($group in $groups)
{
foreach ($domain in $domains)
{
try
{
$adGroup = Get-ADGroup $group -Server $domain
$members = (Get-ADGroupMember $adGroup -Server $domain).where({
# Here, I assume your looking only for user objects
# since you're next cmdlet is Get-ADUser
$_.ObjectClass -eq 'user'
})
foreach($user in $members)
{
# !!! $adUser = Get-ADUser $user >> This is not needed,
# Get-ADGroupMember already brings you the samAccountName of
# each object
# Here you can cast the result, I assume
# you want your CSV to have the Name of the Group and
# the samAccountName and distinguishedName of each user
[pscustomobject]#{
GroupName = $adGroup.Name
samAccountName = $user.samAccountName
distinguishedName = $user.distinguishedName
}
}
}
catch
{
Write-Warning $_
}
}
}
$result | Export-Csv c:\temp\file.csv -NoTypeInformation
If you change your select statement to:
select-object #{n='groupName';expression={$group}}, samAccountName, distinguishedName
It should output the $group input of Get-ADGroupMember for that column.