Issue with powershell output ad-computer foreach - powershell

$computers = Get-ADComputer -Filter * -Properties * | Where-Object {$_.Name -like "LT*" -or $_.Name -like "PC*" -or $_.Name -like "MC*"} | Select name,lastlogondate
"You have [{0}] computers in domain [{1}]" -f $computers.count, (get-addomain).dnsroot
$today = Get-Date
$monthago = $today.AddDays(-30)
"Looking for systems that have not logged in since $monthago"
foreach ($computer in $computers)
{
if ($computer.lastlogondate -lt $monthago)
{"Computer [$computer] suspect"
"last logon $($computer.lastlogondate)"
""}
}
returns the following result:
Computer [#{name=lt020367; lastlogondate=10/23/2019 11:45:38}] suspect
last logon 10/23/2019 11:45:38
Can someone possibly tell me why my output is resulting in [#{ and how to resolve?

by get-adcomputer [...] | Select name,lastlogondate you are creating an object. To output properties of those objects, simply use:
"Computer [$($computer.name)] suspect"
"last logon $($computer.lastlogondate)"
By the way:
Getting all * properties is not ideal. Always filter as early as you can: -properties lastlogondate (name is always returned). Same goes for -filter "name -like 'LT*' -or name -like 'PC*' -or name -like 'MC*'".
Also be careful as lastlogondate of computer objects in AD is not synced between domain controllers.

Related

How to correct an AD script in power shell

I make this script. This script counts how many users have each OU into the two Principal OU's ( RDS Funcional and VDI Funcional). The script works fine but i need to remove the total count of this two principals OU's. In the Image wants to remove the line RDS Funcional,"723". There an other line with this VDI Funcional,"295"
I need to remove both lines
Also remove the double quotes
Exemple in the image This line is fine -> 4127 Transportes Corporativos,16
Thanks :)
$log = #()
"OU=RDS Funcional,DC=esofitec,DC=loc","OU=VDI Funcional,DC=esofitec,DC=loc" | ForEach-Object {
Get-ADOrganizationalUnit -Filter * -SearchBase $_ | ForEach-Object {
$log += "Processsing {0}" -f $_.distinguishedname
[array] $users = Get-ADUser -Filter "Name -notlike 'test*' -and Name -notlike 'adm*'" -SearchBase $_.distinguishedname
if ($users -ne $null) {
$log += "{0} has {1}" -f $users.name, $users.count
[PSCustomObject]#{
OU = $_.name
Users = "{0}" -f $users.count
}
}
}
} | Export-Csv -Path c:\\ExportUsers.csv -NoTypeInformation -Delimiter ','
$log
Example in that Image:
Example
if you do not want the content of selected OU, but only 1st level children OU :
Get-ADOrganizationalUnit -SearchScope OneLevel -Filter * -SearchBase $_

Powershell, find users that were disabled in the past 14 days only

I have a powershell script that his output is showing me everything that was disabled for the past 14 days.
What i'm looking is to change that this script will run from a specific OU and not the whole DC.
I want him to show me only the disabled users for the past 14 days from a specific OU.
The script:
$date = (Get-Date).AddDays(-14)
$disabledUsers = Get-ADObject -Filter 'ObjectClass -eq "User" -and whenChanged -ge $sixMonthsAgo -and UserAccountControl -band 2'
$server = Get-ADDomainController
foreach ($disabledUser in $disabledUsers)
{
Get-ADReplicationAttributeMetadata $disabledUser -Server $server -Properties UserAccountControl |
Where-Object { $_.AttributeName -eq 'UserAccountControl' } | Select Object, LastOriginatingChangeTime |
Where-Object { $_.LastOriginatingChangeTime -gt $date }
}
You should be aware that your current script actually works only if an object has not been modified since it was disabled.
But as far as I know, it is the only way without logging specificly userAccountControl attribute modification (and this cannot still log 100% of cases since once disabled, an object can see his userAccountControl modified without enabling it).
Based on "user is never modified after he was disabled" :
Search-ADAccount -SearchBase "OU=myOU,DC=mydom,DC=adds" -AccountDisabled -UsersOnly | Get-ADUser -Properties whenChanged | Where whenChanged -gt (Get-Date).AddDays(-14)
Using the Filter will make it run quickly
$date = (Get-Date).AddDays(-14)
get-aduser -filter {Enabled -eq $false -and Modified -ge $date } -Properties Modified | select samaccountname,Modified

Powershell last logon query. Help setting up array to go thought all my domain controllers

This script below works, but every attempt I make to have it cycle through all my domain controllers fail. How do I add a array to go through all these OUs on all my domain controllers. Thanks in advance!
$OUs= “OU=Test1,OU=Test1,OU=Test1,OU=Test1,OU=All Users,DC=domain,DC=local",
"OU=Test2,OU=Test2,OU=Test2,OU=All Users,OU=Test2,DC=domain,DC=local",
"OU=Test3,OU=Test3,OU=Test3,OU=All Users,OU=Test3,DC=domain,DC=local",
"OU=test4,OU=test4,OU=test4,OU=All Users,OU=test4,DC=domain,DC=local",
"OU=Test5,OU=test5,OU=Test5,OU=All Users,OU=test5,DC=domain,DC=local”
$OUs | ForEach-Object
{
Get-ADUser -Filter {Enabled -eq $TRUE} -SearchBase $_ -Properties Name,SamAccountName,LastLogonDate |
Where-Object {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)}
} |
Sort LastLogonDate |
Format-Table -Property Name,SamAccountName,LastLogonDate, DistinguishedName |
Out-String
Below you have now an array of your OUs. Please try whether that works for you now.
$OUs= #(
“OU=Test1,OU=Test1,OU=Test1,OU=Test1,OU=All Users,DC=domain,DC=local",
"OU=Test2,OU=Test2,OU=Test2,OU=All Users,OU=Test2,DC=domain,DC=local",
"OU=Test3,OU=Test3,OU=Test3,OU=All Users,OU=Test3,DC=domain,DC=local",
"OU=test4,OU=test4,OU=test4,OU=All Users,OU=test4,DC=domain,DC=local",
"OU=Test5,OU=test5,OU=Test5,OU=All Users,OU=test5,DC=domain,DC=local”
)
I would also suggest to break your line after every pipe in order to cut the line. That makes it far easier to read for you, plus your colleagues.
$OUs | ForEach-Object
{
Get-ADUser -Filter {Enabled -eq $TRUE} -SearchBase $_ -Properties Name,SamAccountName,LastLogonDate |
Where-Object {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)}
} |
Sort LastLogonDate |
Format-Table -Property Name,SamAccountName,LastLogonDate, DistinguishedName |
Out-String
You mention cycling through your domain controllers, but then you go on to ask about OUs. I suspect you want DC's, because each DC might have a different Last Logon Time for the user.
You can omit the -SearchBase and search all OU's, if you're looking to get this data for all users.
$Domains = Get-ADDomainController -Filter * #Note, this shows all DCs- you may have some without ADWS Installed, which won't handle the WHERE.
foreach ($domain in $Domains) {
Get-ADUser -Filter {Enabled -eq $TRUE} -Server $domain -Properties Name,SamAccountName,LastLogonDate |
Where {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)} |
Export-CSV -Path 'UsersNotRecentlyLoggedIn.CSV' -Append
}
If you only want one DC, but all OUs
$Domains = Get-ADDomainController -Discover -Service ADWS
foreach ($domain in $Domains) {
Get-ADUser -Filter {Enabled -eq $TRUE} -Server $domain -Properties Name,SamAccountName,LastLogonDate |
Where {($_.LastLogonDate -lt (Get-Date).AddDays(-7)) -and ($_.LastLogonDate -ne $NULL)} |
Export-CSV -Path 'UsersNotRecentlyLoggedIn.CSV' -Append
}

Select users from AD randomly

We've been tasked with creating a process to review random employee's web traffic on a quarterly basis. I have started a script in Powershell that selects 10 random users from a specific OU, but I'm still getting some unneeded data. I need help filtering down the list further. The output gives me users that have been disabled and left in the OU as well as PRN employees that haven't signed on in a long time. I would like to search AD accounts that has an email address & a logon, modified within the last 3 months. Here is an example of the code I have so far.
Get-ADUser -SearchBase "ou=ouname,ou=ouname,dc=domainname,dc=suffix" -Filter * | Select-Object -Property Name | Sort-Object{Get-Random} | select -First 10
[Edit: Question Answered]
Here is my final script, added $_.passwordlastset as a search attribute since this will pickup users that have changed their password in the last 90 days.
$DateFrom = (get-Date).AddDays(-90)
Get-ADUser -Properties * -Filter {enabled -eq $True} -SearchBase "ou=ouname,dc=domainname,dc=suffix" | where { $_.passwordlastset -gt $DateFrom -and $_.mail -ne $null } | Sort-Object {Get-Random} | select name, sAMAccountName -First 10
Get-ADUser -Properties name, mail, lastlogondate -Filter {enabled -eq $True} -SearchBase "ou=ouname,ou=ouname,dc=domainname,dc=suffix" | select name, mail, lastlogondate | where { $_.lastlogondate -gt (Get-Date).AddDays(-90) -and $_.mail -ne $null }
Here a start.
Try this:
$timeFrame = (get-Date).AddDays(-90)
get-aduser -SearchBase 'ou=ouname,ou=ouname,dc=domainname,dc=suffix' -Filter * -Properties * |
Where-Object {$_.whenChanged -gt $timeFrame -and $_.mail -ne $null} |
Select-Object -Property Name | Sort-Object{Get-Random} | select -First 10
Change the -Filter value:
# LastLogontimeStamp is not guaranteed to be updated on every login, so 30 days + 14 days margin
$threshold = (Get-Date).AddDays(-44).ToFileTime()
Get-ADUser -Filter {Enabled -eq $true -and LastLogontimeStamp -gt $threshold} -SearchBase "ou=ouname,ou=ouname,dc=domainname,dc=suffix" | Sort-Object {Get-Random} | Select Name -First 10
This filter will ensure that AD only returns Enabled users and that their lastLogontimeStamp value has been updated within the last month and a half
This will do everythign the OP stated:
$timeFrame = (get-Date).AddDays(-90)
get-aduser -SearchBase 'YourOU,DC=Domain,DC=com' -Filter * -Properties * |
Where-Object {$_.whenChanged -lt $timeFrame -and $_.mail -ne $null -and $_.Enabled -eq $true} |
Select-Object -Property Name | Sort-Object{Get-Random} | select -First 10
This should meet all the OPs checkpoints via the snippets:
"I would like to search AD accounts that has an email address"
$_.mail -ne $null
"& a logon"
$_.Enabled -eq $true
"modified within the last 3 months"
$_.whenChanged -lt $timeFrame

List users who have an empty description field in PowerShell

I'm trying to get a list of Active Directory users who have no description set.
I start with getting a list of users:
$users = Get-AdUser -Filter {(Enabled -eq "True" )} -Properties Description
And then I tried these options (to get list of users with no description):
$NoDescrUsers = $users | Where-Object {$_.Description -eq ""}
$NoDescrUsers = $users | Where-Object {$_.Description -eq ''}
$NoDescrUsers = $users | Where-Object $_.Description -eq ""
$NoDescrUsers = $users | Where-Object {$_.Description -match ""}
$NoDescrUsers = $users | Where-Object -not {$_.Description -like '*'}
None of these work (or it returns 0 in a foreach or returns everyone). What should my command look like?
I'm not sure why none of the options you tried worked (it seems like they should). Having Googled the general consensus seems to be that you can do this successfully (and more efficiently) within the initial -filter. For example:
$NoDescrUsers = Get-AdUser -Filter {(Enabled -eq "True" ) -and (description -notlike '*')} -Properties Description
If you filter description -like or -notlike
'*'
) that means you'll take any character (or not).
If you want filter only empty description in your AD request, you could do:
$NoDescrUsers = Get-AdUser -Filter {(Enabled -eq "True" ) -Properties Description
if ($NoDescrUsers.Description -eq $null)
{write-host "no description"}