History: I'm making a Powershell script in order to create user from a defined table containing list of users and put them in a defined OrganizationalUnit.
Problem: At the end of the script, I'd like to have a report in order to list whether or not there is one or many user account disabled amoung newly created account
In my script, I have to input a password for each user, but I may enter a password that won't meet the password policy defined in Active Directory; in this case, the account will be created but disabled.
To proceed, I tried :
dsquery user "ou=sp,dc=mydomain,dc=local" -disabled
and it print me this :
"CN=user1,OU=SP,DC=mydomain,DC=local"
"CN=user2,OU=SP,DC=mydomain,DC=local"
"CN=user3,OU=SP,DC=mydomain,DC=local"
My goal : I'd like to extract in a variable the values in "CN" field in order to compare them to the inital user table in my script.
dsquery user "dc=mydomain,dc=local" -disabled | where-object {$_.CN -ne $null}
or
dsquery user "dc=mydomain,dc=local" -disabled | where-object {$_.Common-Name -ne $null}
But it didn't help (doesn't work). How can I proceed please?
It's not tested - just "from my mind"
$csvData = Import-Csv 'UserList.csv' -Delimiter ';' -Encoding UTF8
$userList = dsquery user "ou=sp,dc=mydomain,dc=local" -disabled
$listOfDisabledAccounts = #()
foreach ($user in $userList)
{
if ($csvData.Name -contains (($user -split ',')[0] -replace 'CN=',''))
{
$listOfDisabledAccounts += $csvData.Name
}
}
$listOfDisabledAccounts
dsquery is not a PowerShell cmdlet, but an executable. This means that it is not going to return PowerShell objects to the pipeline. Kongstead's method works off of the knowing that it returns string output. By manipulating the string using split and replace you can get the output into something usable for your purposes. The other two methods to get this information would be to use the the AD module (from RSAT on desktop OSs) and ADSI methods from .Net. Both of these would return data that would be directly usable.
The AD cmdlets would be the easiest. To get all the disabled accounts would look something like this:
Search-ADAccount -AccountDisabled -SearchBase "dc=mydomain,dc=local"
The following example uses PowerShell's match function to parse the CN field, similar to the answer from Kongsted. It should help you achieve what you are looking for, if using AD cmdlets is not an option.
#This is the output from your current query, from the question, it appears to be an array.
$output = ("CN=user1,OU=SP,DC=mydomain,DC=local","CN=user2,OU=SP,DC=mydomain,DC=local","CN=user3,OU=SP,DC=mydomain,DC=local")
$disabledAccs = #()
foreach ($line in $output) {
#match everything after CN= up to the next comma
if([string]$line -match "CN=([^,]*)"){
$disabledAccs += , $Matches[1]
}
}
Related
First time poster but site has helped me so much in the past.
We are an MSP and regularly get requests from clients to pull various details off a list of users they send us. Unfortunately though their lists rarely (if ever) contain any unique identifiers for AD such as samAccountName or even e-mail.
So typically I only get their first and last names, job titles etc. and use a slight variation on the below to try and get the required samAccountNames to work in batch modify scripts.
Get Samaccountname from display name into .csv
The problem comes (and caused a big headache recently) when I try to put that output back into a table to line up with the displaynames. As if the script can't find the displayname it just moves onto the next one in the list and puts the samAccountName directly below the last one it found. making it out of line with the displayname column I've put it beside.
My question is is there something I can add to the below script that when an error occurs it simply inputs null or similar into the samAccountName output csv so I could spot that easily in an excel sheet.
Similarly some users have multiple accounts like an admin and non-admin account with the same display name but different samAccountName so it pulls both of them, which is less of a problem but also if there was any way to have the script let me know when that happens? That would be super useful for future.
Import-Module activedirectory
$displayname = #()
$names = get-content "c:\temp\users.csv"
foreach ($name in $names) {
$displaynamedetails = Get-ADUser -filter { DisplayName -eq $name } -server "domain.local"| Select name,samAccountName
$displayname += $displaynamedetails
}
$displayname | Export-Csv "C:\temp\Samaccountname.csv"
So the problem lies in that you rely on Get-ADUser to provide you with user objects and when it doesn't you have gaps in your output. You instead need to create an object for every name/line in your "csv" regardless of whether Get-ADUser finds anything.
Get-Content 'c:\temp\users.csv' |
ForEach-Object {
$name = $_
$adUser = Get-ADUser -Filter "DisplayName -eq '$name'" -Server 'domain.local'
# Create object for every user in users.csv even if Get-ADUser returns nothing
[PSCustomObject]#{
DisplayName = $name # this will be populated with name from the csv file
SamAccountName = $adUser.SamAccountName # this will be empty if $adUser is empty
}
} | Export-Csv 'C:\temp\Samaccountname.csv'
I am attempting to run a script against our AD that spits out the AD Users in a group, for all the groups in a list. Essentially attempting to audit the groups to find the users. I have a functioning script, except I have no way to determine when the output of one group ends, and where the output of the next begins.
I have tried looking for previous examples, but nothing fits exactly the method I am using, and with me just dipping my toes into powershell I have not been able to combine other examples with my own.
$groups = Get-Content "C:\Folder\File_with_lines_of_ADGroup_Names.txt"
foreach ($group in $groups) { Get-ADGroupMember -Identity "$group" | Where-Object { $_.ObjectClass -eq "user" } | Get-ADUser -Property Description,DisplayName | Select Name,DisplayName,Description,$group | Export-csv -append -force -path "C:\Folder\File_of_outputs.csv" -NoTypeInformation }
Right now the problem lies with getting the $group variable to be exported along with the Name, DisplayName, and Description of each user returned. This is the best way I can think of to tag each user's group and keep all the results in a single file. However, only the first line of results works which is the HEADERS of the CSV, and everything after it is either listed as "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection"or simply blank after the first group of results.
Hoping someone can show me how to easily add my variable $group to the output for each user found for filtering/pivoting purposes.
Thanks and let me know if you have questions.
I believe what you are after are calculated properties on your select statement.
Select Name,DisplayName,Description,$group
Should Probably be something like
Select Name,DisplayName,Description,#{n='Group'; e={$group};}
See also https://serverfault.com/questions/890559/powershell-calculated-properties-for-multiple-values
I need to recreate hundreds of distribution groups in a new (O365) environment. I’ve no access to the source system other than to work with their techs to provide them scripts that they’ll run for me.
I wrote a script to spit out the names of all the lists that my users are members of (security and distribution). I’d like to write another to cycle through each distribution group and provide me with details of that group. I don’t see how to do that.
I see that Set-DistributionGroup will happily let me set the AcceptMessagesOnlyFromDLMembers (and a million other fields) but I don’t see that Get_DistributionGroup will output those values for me. How do I do this to ensure I’m not recreating an open group for HR that should have been MemberJoinRestriction enabled (for example)?
Thanks in advance.
Okay so I'm not a PowerShell guy (obvs.), but here's what I wrote that works. I'm sure I'm not taking advantage of PowerShell at all here, so wanna suggest how I could improve? Like why did I have to use $temp? Quicker to check the array first before I Get-ADGroup again? etc.
# Start with a user list, get the groups eash is a part of, get information about the group
# if it is mail-enabled then add it to an array, remove duplicates, then store all the
# information about that DistributionGroup into a .csv
$groups = #()
ForEach ($user in $(Get-Content c:\Users\sid.sowder\Desktop\CEGusers.txt)) {
$MyGroups = Get-ADuser $user -Properties * | select memberof -ExpandProperty memberof
ForEach ($MyGroup in $MyGroups) {
$temp = Get-ADGroup $MyGroup -Properties *
if ($temp.mail -ne $null) {
$groups += $temp.SamAccountName
}
}
}
$groups = $groups | sort -unique
Foreach ($group in $groups) {
Get-DistributionGroup -Identity $group |
Select * |
Export-CSV C:\Users\Sid.Sowder\Desktop\distlistdetail.csv -NoTypeInformation -Append
}
I would like to write a PS script that exports a .csv for all users that are specified in a separate .txt file. So, for instance, I could create a text file that has
Timmy Turner
Silly Sally
Then, when the script is ran, it searches AD for those two users and exports a CSV with their first name, last name, and email address.
I originally got hung up a bit on how the "Get-ADUser" filter worked, but I produced something semi-usable. However, what I've come up with just asks who you are searching for and then uses that. I think it would be much easier to just have it reference a pre-made text file, especially when searching for a large number of users. Or, there may be an even easier way to do this that I am not thinking of. Here is what I currently have:
$SamAc = Read-Host 'What is the first and last name of the person you would like to search for?'
$filter = "sAmAccountname -eq ""$SamAc"""
Get-ADUser -Filter $filter -Properties FirstName, LastName, EmailAddress | select FirstName, LastName, EmailAddress | Export-CSV "C:\Scripts\PS_ADQuery\Email_Addresses.csv"
I feel like the "Get-Content" cmdlet is close to what I am looking for, but I can't seem to get it to function correctly. I may be going in the totally wrong direction, though.
I found the answer. It turns out I even had the AD properties totally wrong. Take my comments with a grain of salt since I may not fully understand the processes behind each line of code, but this does exactly what I was looking to do.
#creates a $users variable for each username listed in the users.txt file. the ForEach
#command allows you to loop through each item in the users.txt array. the scriptblock
#nested into the ForEach command queries each username for specific properties.
$users = ForEach ($user in $(Get-Content C:\Scripts\PS_ADQuery\users.txt)) {
Get-AdUser $user -Properties GivenName,sn,mail
}
#takes the $users variable defined by the ForEach command and exports listed properties
#to a csv format.
$users |
Select-Object GivenName,sn,mail |
Export-CSV -Path C:\Scripts\PS_ADQuery\output.csv -NoTypeInformation
I have a CSV file that looks like this:
name
fname1lname1#companyemail.com
fname2lname2#companyemail.com
...
I would like to loop through each email address and query AD for that address to grab the user objects ID. I have been able to do this using a script, but I would like to be able to do it using just one line.
This is what I've done so far:
import-csv -path .\csv_file.csv | foreach-object { get-aduser -filter { proxyaddresses -like "*$_.name*} | select name } | out-file .\results.csv
This obviously doesn't work and I know it has something to do with how I am handling my $_ object in the foreach loop.
I'm hoping for the output to look something like:
fname1lname1#companyemail.com,userID1
fname2lname2#companyemail.com,userID2
...
You are filtering on the property proxyaddresses however that is not part of the default property set that Get-AdUser returns. Also your code had a errant " which might have been a copy paste error.
Import-CSV -Path .\csv_file.csv | ForEach-Object {
Get-ADUser -Filter "ProxyAddresses -like '*$($_.name)*'" -Properties ProxyAddresses,EmailAddress | select EmailAddress,SamAccountName
} | Export-CSV .\results.csv -NoTypeInformation
-Filter can be tricky sometimes as it is looking for string input. Wrap the whole thing in quotes and use a sub expression to ensure that the variable $_.Name is expanded properly and has is asterisks surrounding it.
Since you are also looking for emailaddress we add that to the properties list as well. I will assume the second column is for samaccountname.
We also use Export-CSV since that will make for nice CSV output.
If you're using Exchange this can be much simpler and faster if you use the Exchange cmdlets:
Import-CSV -Path .\csv_file.csv | ForEach-Object {
Get-Recipient $_ |
Select PrimarySMTPAddress,SamAccountName
} | Export-CSV .\results.csv -NoTypeInformation
Exchange requires all email address to be unique, and maintains it's own internal database that uses email address as a primary index so it can return the DN and SamAccountName that goes with that email address almost immediately.
AD doesn't require them to be unique, so it doesn't index on that attribute and it has to search every user object looking for the one that has that email address in it's proxy address collection.