I have a quick script I am trying to reuse from getting computers lastlogon. Due to time constraints I am posting it here for assistance. I am trying to use the display name and even tried using the sam, but no luck.
$results = #()
$CompanyUsers = import-csv c:\bin\users.csv
foreach ($i in $CompanyUsers)
{
$results += Get-Aduser -Filter $i.sam -Properties * | select Name, Lastlogondate
#$results += Get-Aduser -Filter {displayname -eq $i.displayname} -Properties * | select Name, Lastlogondate
}
$results | export-csv c:\bin\Userslogon.csv
I get syntax errors. I can manually put in the values so I am thinking it has to do with data types extracted from the array. Suggestions would be appreciated!
SAM ERROR:
Get-Aduser : Error parsing query: 'xxx001' Error Message: 'syntax error' at position: '1'.
At C:\bin\Get-UserLastLogon.ps1:19 char:14
+ $results += Get-Aduser -Filter $i.sam -Properties * | select Name, Lastlogondat ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:) [Get-ADUser], ADFilterParsingException
+ FullyQualifiedErrorId : Error parsing query: 'kal001' Error Message: 'syntax error' at posi
tion: '1'.,Microsoft.ActiveDirectory.Management.Commands.GetADUser
DISPLAYNAME ERROR:
Get-Aduser : Property: 'displayname' not found in object of type:
'System.Management.Automation.PSCustomObject'.
At C:\bin\Get-UserLastLogon.ps1:20 char:17
+ $results += Get-Aduser -Filter {displayname -eq $i.displayname} -Properties ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADUser], ArgumentException
+ FullyQualifiedErrorId : Property: 'displayname' not found in object of type: 'System.Manage
ment.Automation.PSCustomObject'.,Microsoft.ActiveDirectory.Management.Commands.GetADUser
Thanks for the suggestions. I found a way to get this to work:
# Create array of users
$results = #()
$Users = Get-Content C:\bin\fullnames.txt
# Get last logon date
foreach($i in $Users)
{
$results += Get-ADUser -ldapfilter "(displayname=$i)" -Property * | Select-Object -Property name, samaccountname, lastlogondate
}
# Export results to csv file
$results | export-csv c:\bin\logonusers.csv
Try one of these:
Get-Aduser -Filter "samaccountname -eq '$i.sam'" -Properties *
Get-Aduser -Filter "displayname -eq '$i.displayname'" -Properties *
The samaccountname will be faster, since that's an indexed property.
# Create array of users
$results = #()
$Users = Get-Content C:\bin\fullnames.txt
# Get last logon date
foreach($i in $Users)
{
$results += Get-ADUser -ldapfilter "(displayname=$i)" -Property * | Select-Object -Property name, samaccountname, lastlogondate
}
# Export results to csv file
$results | export-csv c:\bin\logonusers.csv
Related
I'm trying to run a script to get a list of PCs and exporting it to a csv file.
When I run it, it returns a "The server has returned the following error: invalid enumeration context." error.
Below is my script:
Get-ADComputer -Filter * -Property * | Select-Object Created,Name,OperatingSystem,ipv4Address,DistinguishedName | Export-CSV test.csv -NoTypeInformation -Encoding UTF8
I made some changes:
$properties = 'Created','Name','OperatingSystem','OperatingSystemVersion','ipv4Address','DistinguishedName'
Get-ADComputer -Filter * -Properties $properties | Export-CSV test.csv -NoTypeInformation -Encoding UTF8
But I'm still getting the enumeration error.
Another update:
The code was giving an error so I thought maybe I needed to set the execution policy to Unrestricted, but that also didn't fix the issue.
I have a new error now along with the enumeration error.
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
$properties = #(
'Created'
'Name'
'OperatingSystem'
'ipv4Address'
'DistinguishedName'
)
Get-ADOrganizationalUnit -Filter * | ForEach-Object {
Get-ADComputer -Filter * -Properties $properties -SearchBase $_.DistinguishedName
} | Select-Object $properties | Export-CSV test.csv NoTypeInformation -Encoding UTF8
Here are the errors (odd because AD is not down):
Get-ADComputer : Unable to contact the server. This may be because this server does not exist, it is currently down, or it does not have the Active Directory Web Services running.
At \\nasinfrastructure.wakefern.com\Infrastructure\Security\Powershell\Susan_Scripts\AD_User_PCs\Get-ADComputer_4All.ps1:12 char:5
+ Get-ADComputer -Filter * -Properties $properties -SearchBase $_.D ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [Get-ADComputer], ADServerDownException
+ FullyQualifiedErrorId : ActiveDirectoryServer:0,Microsoft.ActiveDirectory.Management.Commands.GetADComputer
Get-ADComputer : The server has returned the following error: invalid enumeration context.
At \\nasinfrastructure.wakefern.com\Infrastructure\Security\Powershell\Susan_Scripts\AD_User_PCs\Get-ADComputer_4All.ps1:12 char:5
+ Get-ADComputer -Filter * -Properties $properties -SearchBase $_.D ...
This can happen in a big environment with many objects, I see you have updated your code to query only a specific set of attributes as opposed to querying all (-Properties *) which is a good start. Your best bet to workaround this issue is to query all computers per Organizational Unit.
$properties = #(
'Created'
'Name'
'OperatingSystem'
'ipv4Address'
'DistinguishedName'
)
Get-ADOrgnizationalUnit -Filter * | ForEach-Object {
Get-ADComputer -Filter * -Properties $properties -SearchBase $_.DistinguishedName
} | Select-Object $properties | Export-CSV test.csv -NoTypeInformation -Encoding UTF8
I tried to not bug you all, but I'm at a loss. I'll preface with, I'm still relatively new to PS, so my apologies for any ignorance.
Need: To update users' attribute (extensionAttribute1 to be precise) to "First.Last" (or rather, "givenName.Surname") for all users in AD.
Problem: When I try to run the Powershell below (I was trying 2 different methods for update, hence the commented out portion), I get the outputs below.
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase 'ou=Users,ou=Test,dc=Sample,dc=Com' |
Select SamAccountName |
Export-Csv -Path 'c:\Scripts\AllUsersSamaccountname.CSV' -NoTypeInformation
$file="c:\Scripts\AllUsersSamaccountname.CSV"
(gc $file | select -Skip 1) | sc $file
$Users = Import-Csv -Path "c:\Scripts\AllUsersSamaccountname.CSV" -Header "AccountName"
foreach($User in $Users){
$ADUser = Get-ADUser -Identity $User.AccountName -Properties extensionAttribute1
$ADUserG = Get-ADUser -Identity $User.AccountName -Properties givenName
$ADUserS = Get-ADUser -Identity $User.AccountName -Properties Surname
#$ADUser.extensionAttribute1 = [Array]$ADUserG + '.' + $ADUserS
Set-ADUser -Instance $ADUser -replace #{extensionAttribute1=([Array]$ADUserG + '.' + $ADUserS)}
}
Get-ADUser -Filter * -SearchBase 'ou=Users,ou=Test,dc=George,dc=Com' |
Select extensionAttribute1 |
Export-Csv -Path 'c:\Scripts\new-AllUserinfo6.CSV' -NoTypeInformation
Output for Set-ADUser -Instance $ADUser -replace #{extensionAttribute1=([Array]$ADUserG + '.' + $ADUserS)
Set-ADUser : Cannot validate argument on parameter 'Replace'. All values in the argument collection should be of
the same type.
At line:17 char:44
+ ... er -replace #{extensionAttribute1=([Array]$ADUserG + '.' + $ADUserS)} ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Set-ADUser], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.Set
ADUser
Output for #$ADUser.extensionAttribute1 = [Array]$ADUserG + '.' + $ADUserS
Exception setting "extensionAttribute1": "The adapter cannot set the value of property "extensionAttribute1"."
At line:16 char:6
+ $ADUser.extensionAttribute1 = [Array]$ADUserG + '.' + $ADUserS
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : CatchFromBaseAdapterSetValue
Any help or guidance would be greatly appreciated...
You are casting the givenName to an array. More than likely that's causing the whole expression to return an array, which isn't acceptable for extensionAttribute1.
I didn't test this but rewriting the loop to something like below should work:
foreach($User in $Users)
{
$ADUser = Get-ADUser -Identity $User.AccountName -Properties extensionAttribute1
$ADUserG = Get-ADUser -Identity $User.AccountName -Properties givenName
$ADUserS = Get-ADUser -Identity $User.AccountName -Properties Surname
$extensionAttribute1 = ($ADUserG.givenName + '.' + $ADUserS.Surname)
$ADUser.extensionAttribute1 = $extensionAttribute1
Set-ADUser -Instance $ADUser
}
Note: that you must reference the properties for givenName & Surname in order to concatenate them as strings. Otherwise you are trying to add 2 user objects together and will get an error.
Additional Info:
If this were me I would write this to be more concise. However, considering you are relatively new to PowerShell, I'd just make one recommendation. In the loop you don't need to get the user account multiple times, something like the below should work and be a little faster.
Import-Module ActiveDirectory
Get-ADUser -Filter * -SearchBase 'ou=Users,ou=Test,dc=Sample,dc=Com' |
Select-Object SamAccountName |
Export-Csv -Path 'c:\Scripts\AllUsersSamaccountname.CSV' -NoTypeInformation
$file="c:\Scripts\AllUsersSamaccountname.CSV"
(Get-Content $file | Select-Object -Skip 1) | Set-Content $file
$Users = (Import-Csv -Path "c:\Scripts\AllUsersSamaccountname.CSV" -Header "AccountName")
foreach($User in $Users)
{
$ADUser = Get-ADUser -Identity $User.AccountName -Properties 'extensionAttribute1','givenName','Surname'
$extensionAttribute1 = ($ADUser.givenName + '.' + $ADUser.Surname)
$ADUser.extensionAttribute1 = $extensionAttribute1
Set-ADUser -Instance $ADUser
}
Get-ADUser -Filter * -SearchBase 'ou=Users,ou=Test,dc=George,dc=Com' |
Select-Object extensionAttribute1 |
Export-Csv -Path 'c:\Scripts\new-AllUserinfo6.CSV' -NoTypeInformation
I want to return the group names in a semicolon delimited list for each AD user in an array. Here is what I have so far:
$ADuser = Get-ADUser -filter * -Properties * | ? {$_.employeeNumber -eq " 9408" -or $_.employeeNumber -eq "3816"} | Select-Object Name,SamAccountName,UserPrincipalName,DisplayName,GivenName,Surname,description,mail,Enabled,HomeDirectory,distinguishedname,MemberOf
foreach($user in $ADuser)
{
$Groups = forEach ($group in $ADuser.memberOf)
{
(Get-ADGroup $group).name
}
$groupStr = $Groups -join ";"
$ADuser = $ADuser | Select-Object Name,SamAccountName,UserPrincipalName,DisplayName,GivenName,surname,description,mail,Enabled,HomeDirectory,distinguishedname,#{n='Groups';e={$groupStr}}
}
This code works fine when $ADuser contains a single user. When $ADuser contains more than one user, I get the following error each time it tries to set Groups:
Get-ADGroup : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At line:8 char:22
+ (Get-ADGroup $group).name
+ ~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-ADGroup],
ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADGroup
I expect the output to be like this for each $ADuser:
Name : John.Doe
SamAccountName : John.Doe
UserPrincipalName : John.Doe#mydomain.com
DisplayName : John Doe
GivenName : John
Surname : Doe
description : Joe is a person
mail : John.Doe#mydomain.com
Enabled : True
HomeDirectory : \\fileserver\homefolders\John.Doe
distinguishedname : CN=John.Doe,OU=People,OU=my,DC=domain
Groups : Group1;Group2;Group3;Group4
Looks like you have messed up with these two variables: $ADUsers and $users.
$ADuser = Get-ADUser -filter * -Properties * | ? {$_.employeeNumber -eq " 9408" -or $_.employeeNumber -eq "3816"} | Select-Object Name,SamAccountName,UserPrincipalName,DisplayName,GivenName,Surname,description,mail,Enabled,HomeDirectory,distinguishedname,MemberOf,Groups
$Results = New-Object System.Collections.ArrayList
foreach($user in #($ADuser))
{
$Groups = forEach ($group in #($user.memberOf))
{
(Get-ADGroup $group).name
}
$user.Groups = $Groups -join ';'
[Void]$Results.Add($user)
}
$Results
Kirill Pashkov's helpful answer solves your immediate problem.
To take a step back:
Your symptoms suggest that you're running on PSv2, which has the following implications:
Member-access enumeration (PSv3+) isn't available; that is, if $ADuser is an array (a collection), you cannot use .memberOf to implicitly collect the .memberOf property values of its elements.
A foreach (...) { ... } loop executes its loop body even if the value to enumerate is $null - in PSv3+ the loop body isn't executed at all.
That said, your code can presumably be reduced to this one command:
Get-ADUser -Properties * |
? {$_.employeeNumber -eq " 9408" -or $_.employeeNumber -eq "3816"} |
Select-Object Name,
SamAccountName,
UserPrincipalName,
DisplayName,
GivenName,
Surname,
description,
mail,
Enabled,
HomeDirectory,
distinguishedname,
#{
n='Groups';
e={ ($_.memberOf | Get-AdGroup | Select-Object -ExpandProperty Name) -join ";" }
}
My main goal is to export some info about users from Active Directory to CSV file.
But in my AD, there is also bunch of some service accounts that I don't want to export and I want to use only specific OUs.
So I created CSV file with "list" of these OUs and filenames of exported CSV, looks like:
oubase,oucity,filename
OU=_SubCompany1,OU=_City1,filename1.csv
OU=_SubCompany1,OU=_City2,filename2.csv
OU=_SubCompany3,OU=_City1,filename3.csv
And my PS script:
Import-Module ActiveDirectory
$adserver = "ad1.domain.com"
$filter = "'(& (msExchMailboxGuid=*) (!sAMAccountName=*_*))'"
$selection = "personalTitle, msDS-PhoneticFirstName, msDS-PhoneticLastName, msDS-PhoneticDepartment, Title, mobile, telephoneNumber, facsimileTelephoneNumber, SamAccountName"
$targetpath = "C:\Scripts\ADUsers\export\"
$exportfiles = "C:\Scripts\ADUsers\export\export_files.csv"
Import-Csv -Path $exportfiles | ForEach-Object {
$oubase = $_.'oubase'
$oucity = $_.'oucity'
$filename = $_.'filename'
$fullpath = $targetpath + $filename
$fullbase = "'OU=Users," + $oucity + "," + $oubase + ",DC=domain,DC=com'"
#$fullbase = 'OU=Users,OU=_City2,OU=_SubCompany1,DC=domain,DC=com'
Get-ADUser -Server $adserver -LDAPFilter $filter -Properties * -SearchBase $fullbase |
select $selection |
Export-Csv -Encoding Unicode $fullpath
But the script isn't working. There is some problem with variables in the Get-ADUser command.
When I type in directly all the values, everything is working:
Get-ADUser -Server ad1.domain.com -LDAPFilter '(& (msExchMailboxGuid=*) (!sAMAccountName=*_*))' -Properties * -SearchBase 'OU=Users,OU=_City2,OU=_SubCompany1,DC=domain,DC=com' |
select personalTitle, msDS-PhoneticFirstName, msDS-PhoneticLastName, msDS-PhoneticDepartment, Title, mobile, telephoneNumber, facsimileTelephoneNumber, SamAccountName |
Export-Csv -Encoding Unicode C:\Scripts\ADUsers\export\filename2.csv
When I try to display the content of variables, it seems OK, no extra whitespaces or commas etc.
I think variables $filter and $fullbase are problematic.
When I try it like with $filter variable, command won't return any error and it creates empty CSVs:
Get-ADUser -Server $adserver -LDAPFilter $filter -Properties * -SearchBase 'OU=Users,OU=_City2,OU=_SubCompany1,DC=domain,DC=com' |
select personalTitle, msDS-PhoneticFirstName, msDS-PhoneticLastName, msDS-PhoneticDepartment, Title, mobile, telephoneNumber, facsimileTelephoneNumber, SamAccountName |
Export-Csv -Encoding Unicode C:\Scripts\ADUsers\export\filename2.csv
When I try it with $fullbase variable, command returns this error.
Get-ADUser -Server $adserver -LDAPFilter '(& (msExchMailboxGuid=*) (!sAMAccountName=*_*))' -Properties * -SearchBase $fullbase |
select personalTitle, msDS-PhoneticFirstName, msDS-PhoneticLastName, msDS-PhoneticDepartment, Title, mobile, telephoneNumber, facsimileTelephoneNumber, SamAccountName |
Export-Csv -Encoding Unicode C:\Scripts\ADUsers\export\filename2.csv
Get-ADUser : The supplied distinguishedName must belong to one of the following
partition(s): 'DC=domain,DC=com , CN=Configuration,DC=domain,DC=com ,
CN=Schema,CN=Configuration,DC=domain,DC=com , DC=DomainDnsZones,DC=domain,DC=com ,
DC=ForestDnsZones,DC=domain,DC=com'.
At C:\Scripts\ADUsers\export\ad-users_export-csv.ps1:21 char:1
+ Get-ADUser -Server $adserver -LDAPFilter '(& (msExchMailboxGuid=*) (!sAMAccountN ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADUser], ArgumentException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
Do you have any ideas what am I doing wrong?
Below are my current attempts to pull AD groups whose managedby equal names like "ML...". I keep getting errors so I wanted to know why I am unable to filter managedby with "-like" when I can filter managedby "-eq $..." variables. I tried making a variable $name = "ML*" so that I can perform {managedby -eq $name} but still had no luck.
I mostly get error like:
Operator(s): The following: ''Eq', 'Ne'' are the only operator(s) suppor
ted for searching on extended attribute: 'ManagedBy'.
and so forth because "-eq" is only accepted for some filters I have done. When I use -eq I get these errors:
Import-Module : The following error occurred while loading the extended type dat
a file:
Microsoft.PowerShell, C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\ActiveD
irectory\ActiveDirectory.Types.ps1xml : File skipped because it was already pres
ent from "Microsoft.PowerShell".
Microsoft.PowerShell, C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\ActiveD
irectory\ActiveDirectory.Types.ps1xml : File skipped because it was already pres
ent from "Microsoft.PowerShell".
At J:\\ManagedbyEqualsML.ps1:1 char:14
+ Import-Module <<<< ActiveDirectory
+ CategoryInfo : InvalidOperation: (:) [Import-Module], RuntimeExc
eption
+ FullyQualifiedErrorId : FormatXmlUpateException,Microsoft.PowerShell.Comm
ands.ImportModuleCommand
The term 'Get-adgroup' is not recognized as the name of a cmdlet, function, scri
pt file, or operable program. Check the spelling of the name, or if a path was i
ncluded, verify that the path is correct and try again.
At J:\\ManagedbyEqualsML.ps1:53 char:27
+ $MLgroupAll = Get-adgroup <<<< -Properties managedby, enabled, name -filter
{managedby -eq $name}
+ CategoryInfo : ObjectNotFound: (Get-adgroup:String) [], CommandN
otFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Here are my codes where I attempted to find Owners that have the name ML*
Import-Module ActiveDirectory
$name = "ML*"
#Attempt 1
$MLgroups = Get-adgroup -Properties managedby, enabled, name -filter * | Select name, managedby
foreach ($group in $MLgroups){
if ($group.managedby -like "ML*"){
write-host $group.name + $group.managedby}
}
#Attempt 2
$Mgroups = get-adgroup -Properties name, managedby -filter *
foreach ($groups in $Mgroups){
# here get the group name and use the "managedBy attribute to retrieve the user object
# grou naem
$gname = $_.Name
$manager=Get-AdUser $_.ManagedBy
$MangerName = $manager.DisplayName
if ($managerName -like "ML*"){
write-host $gname + $managerName}
}
#Attempt 3
$exportlist = "C:\Temp\managedby.txt"
Clear-Content $exportlist
$Header = `
"Group ID Name" + "|" + "ManagedBy"
$Header | Out-File $exportlist -Append
$list = get-adgroup -properties name, managedby -filter {managedby -like "ML_*"} `
| Select name, managedby | Export-CSV $exportlist -NoType -Delimiter '|'
#Attempt 4
$MLgroupAll = Get-adgroup -Properties managedby, enabled, name -filter {managedby -like $name}
foreach ($group in $MLgroupAll) {
write-host $group.name + $group.managedby}
UPDATE: if i try to changed my $name variable it still doesn't work and gives another error.
$MLgroupAll = get-adgroup -Properties managedby, enabled, name -filter {managedby -eq $name}
foreach ($group in $MLgroupAll) {
$managed = $group.managedby
if ($managed -like "ML*"){
write-host $group.name + $group.managedby }
}
ERROR:
Get-ADGroup : Identity info provided in the extended attribute: 'ManagedBy' coul
d not be resolved. Reason: 'Cannot find an object with identity: 'ML*' under: 'D
C=we,DC=dirsrv,DC=com'.'.
#Paul: here is my error still:
Here is an example that works for me (orienting myself at your last try):
get-adgroup -filter * -Properties managedby | % {
if($_.managedby -like "CN=ML*"){
write-host $_.name + $_.managedby
}
}