Disabled ActiveDirectory Users from specific date with exclude list - powershell

i wrote a script that gonna disabled old users...
and i need to do an exclude list to it...
the exclude list should be .csv, with 3 columns "Name","SamaccountName","Reason"...
i'm kind of stuck with the exclude list filtering...
i tried to do -notmatch and -notcontains and nothing worked for me...
i even try to do a foreach with if but the same...
Function Get-ADLockOldUsers {
param ()
begin{
[datetime]$myDate = '01/01/1601 02:00:00'
$colObj = #()
$AllUsers = (Get-ADUser -Filter * -Properties lastLogonTimestamp | ? {$_.Enabled} | Select-Object Name,SamAccountName,#{N="LastLogon";E={[datetime]::FromFileTime($_.lastLogonTimestamp)}})
$AllUsers = $AllUsers | ? {(Get-Date).AddDays(-30) -gt $_.LastLogon -and -not ($_.LastLogon -eq $myDate)}
}
process {
$AllUsers | % {
$obj = New-Object psobject
$obj | Add-Member noteproperty 'Name' $_.Name -Force
$obj | Add-Member noteproperty 'SamAccountName' $_.SamAccountName -Force
$obj | Add-Member noteproperty 'LastLogon' $_.LastLogon -Force
$obj | Add-Member noteproperty 'NeedDisabled' $true -Force
$colObj += $obj
}
}
end { return $colObj }
}
Function Set-ADLockUser {
param()
begin{
if (Test-Path '.\excludeusers.csv') {
$excludeUsers = Import-Csv '.\excludeusers.csv'
$DUser = #()
$colUsers = Get-ADLockOldUsers
$colUsers | ? {$_.SamAccountName -notcontains $excludeUsers} | % {Set-ADUser -Identity $_.SamAccountName -Enabled $false -WhatIf }
}
else { Write-Output "Error! excludeusers.csv cannot be found, stop script"; break }
}
process {
}
end{}
}
Set-ADLockUser

A string value can never contain an array, so
$_.SamAccountName -notcontains $excludeUsers
will always evaluate to $true. You need to reverse the check and make the reference an array of strings (the CSV import produces an array of custom objects). Selecting only the field SamaccountName from the imported CSV and switching the arguments should do what you want:
$excludeUsers = Import-Csv '.\excludeusers.csv' | % { $_.SamaccountName }
...
$colUsers | ? { $excludeUsers -notcontains $_.SamAccountName } | ...
As a side note, you could simplify the the code for finding obsolete accounts like this:
$myDate = Get-Date '01/01/1601 02:00:00'
$limit = (Get-Date).AddDays(-30)
$colObj = Get-ADUser -Filter * -Properties * `
| ? { $_.Enabled } `
| select Name,SamAccountName,#{n="NeedDisabled";e={$true}},
#{n="LastLogon";e={[datetime]::FromFileTime($_.lastLogonTimestamp)}} `
| ? { $limit -gt $_.LastLogon -and $_.LastLogon -ne $myDate }

This is the final solution...
<#
.Synopsis
Get All Users in the Domain and check the last logon Date
.Example
Set-ADLockUser -ReportOnly:$true
Get all users that didn't logon for a 30 days and write a report to the current directory
.Example
Set-ADLockUser -ReportOnly:$false
Get all users that didn't logon for a 30 days and disabled them
.Description
Get All Users in the Domain and check the last logon Date, and exclude some users from a list .\excludeusers.csv
.Parameter ReportOnly
Specifies if the script is in reportmode or active mode if ReportOnly=$false all the relevant users will lock
.Outputs
PSObject[]
.Notes
Name: Set-ADLockUser
Author: Ohad Halali
Date: 14.07.2013
.Link
#>
Function Get-ADLockOldUsers {
param ()
begin{
[datetime]$myDate = '01/01/1601 02:00:00'
$colObj = #()
$AllUsers = (Get-ADUser -Filter * -Properties lastLogonTimestamp | ? {$_.Enabled} | `
Select Name,SamAccountName,#{N="LastLogon";E={[datetime]::FromFileTime($_.lastLogonTimestamp)}}) | `
? {(Get-Date).AddDays(-30) -gt $_.LastLogon -and -not ($_.LastLogon -eq $myDate)}
}
process {
$AllUsers | % {
$obj = New-Object psobject
$obj | Add-Member noteproperty 'Name' $_.Name -Force
$obj | Add-Member noteproperty 'SamAccountName' $_.SamAccountName -Force
$obj | Add-Member noteproperty 'LastLogon' $_.LastLogon -Force
$obj | Add-Member noteproperty 'NeedDisabled' $true -Force
$colObj += $obj
}
}
end { return $colObj }
}
Function Set-ADLockUser {
param([bool]$ReportOnly=$true)
begin{
if (Test-Path '.\excludeusers.csv') {
$excludeUsers = Import-Csv '.\excludeusers.csv'
$colUsers = Get-ADLockOldUsers | ? {$excludeUsers.SamAccountName -notcontains $_.SamAccountName}
if ($ReportOnly) {
$colUsers | Export-Csv '.\Report.csv' -NoClobber -NoTypeInformation -Encoding ASCII -Force
}
else {
$colUsers.SamAccountName | Set-ADUser -SamAccountName $_ -Enabled:$False -Replace #{info="Disabled after no login for 30 days (Script)"} -WhatIf
}
}
else { Write-Output "Error! excludeusers.csv cannot be found, stop script"; break }
}
process {}
end{}
}
Set-ADLockUser

Related

Remove duplicate items in object but not all of it

How can I remove duplicates before exporting to a csv?
foreach ($group in $ADGroups) {
$ADResult += [PSCustomObject]#{
ADGroup = $group.name
ADuser = $user.name
}
#Remove-ADGroupMember -Identity $Group.DistinguishedName -Members $UserInfo.DistinguishedName -Confirm:$false
$group = $null
}
In the above bit of code the result comes out like
aduser | adgroup
x | a
x | s
x | v
The aduser is the same for each group. How can I post the user once
so it comes out like the following without the duplicate user?
aduser | adgroup
x | a
| s
| v
This will create the output as you requested. You'll lose the ability to sort and filter if you plan to work with the output data in Excel but it's your choice.
#Users Group Membership
$ADGroups = Get-ADGroup -Filter *
$groupMembership = foreach ($group in $ADGroups) {
$members = Get-ADGroupMember -Identity $group | Where-Object { $_.objectClass -eq 'user' }
foreach ($member in $members) {
[PSCustomObject]#{
ADuser = $member.name
ADGroup = $group.name
}
}
}
#Get Unique Users
$usersUnique = $groupMembership | Select-Object -Property ADuser -Unique | Sort-Object -Property ADuser
#Loop each Unique user and add a new NoteProperty ADuser2. This will be populated with ADuser if its the first occurrence, else blank.
$results = foreach ($user in $usersUnique) {
$firstOccurrence = $true
$userMembership = $groupMembership | Where-Object { $_.ADuser -eq $user.ADuser } | Sort-Object -Property ADGroup
foreach ($membership in $userMembership) {
if ($firstOccurrence) {
$membership | Add-Member -MemberType NoteProperty -Name ADuser2 -Value $user.ADuser -PassThru
$firstOccurrence = $false
}
else {
$membership | Add-Member -MemberType NoteProperty -Name ADuser2 -Value "" -PassThru
}
}
}
#Export to CSV
$results | Sort-Object -Property ADuser, ADGroup | Select-Object ADuser2, ADGroup | Export-Csv -Path C:\support\user-group_membership_report.csv -NoTypeInformation
I would go with something like this:
$i = 0
foreach ($group in $ADGroups) {
if($i -eq 0){
$ADResult += [PSCustomObject]#{
ADGroup = $group.name
ADuser = $user.name
}
$i = 1
}
else {
$ADResult += [PSCustomObject]#{
ADGroup = $group.name
ADuser = ""
}
}
}

exchange powershell list sendas, send on behalf of, AND fullaccess for a given mailbox

For a given mailbox, I want to list of any users who have any of the following permissions:
send as
send on behalf of
full access
I haven't been able to find a simple way to get all 3 at once, so I have been going at it on a per permission basis...
get-exolmailbox -identity "example#example.com" | get-exolmailboxpermission | where { ($_.AccessRights -eq "FullAccess") -and ($_.IsInherited -eq $false) -and -not ($_.User -like "NT AUTHORITY\SELF") }
get-exolmailbox -Identity "example#example.com" | Get-ADPermission | ? { ($_.ExtendedRights -like "*send*") -or ($_.ExtendedRights -like "*full*") -and -not ($_.User -like "*\self*") } | FT -auto User,ExtendedRights
get-exolmailbox -identity "example#example.com" | fl displayname, grantsendonbehalfto
Is there was a more elegant way to get that same info before I put some time into figuring out how to format the results the way I want?
I would prefer to end up with an excel file that lists each user by display name and which permissions they have to the mailbox.
Something like this should do what you want, it creates a custom object and assigns the info from your commands to its properties.
$emailaddress = "user1#example.com","user2#example.com"
$MailboxPermissions = #()
foreach ($email in $emailaddress)
{
$exolmailbox = get-exolmailbox -identity $email
$FullAccess = $exolmailbox | where { ($_.AccessRights -eq "FullAccess") -and ($_.IsInherited -eq $false) -and -not ($_.User -like "NT AUTHORITY\SELF") }
$SendAs = $exolmailbox | Get-ADPermission | ? { ($_.ExtendedRights -like "*send*") -or ($_.ExtendedRights -like "*full*") -and -not ($_.User -like "*\self*") }
$MailboxInfo = New-Object System.Object
$MailboxInfo | Add-Member -type NoteProperty -name DisplayName -value $exolmailbox.displayname
$MailboxInfo | Add-Member -type NoteProperty -name FullAccess -value $FullAccess
$MailboxInfo | Add-Member -type NoteProperty -name SendAsUser -value $SendAs.User
$MailboxInfo | Add-Member -type NoteProperty -name SendAsExtendedRights -value $SendAs.ExtendedRights
$MailboxInfo | Add-Member -type NoteProperty -name GrantSendOnBehalfTo -value $exolmailbox.grantsendonbehalfto
$MailboxPermissions += $MailboxInfo
}
$MailboxPermissions
Note: I can't test this as I can't find anything online that references get-exolmailbox, and I've only ever seen/used get-mailbox before.

Folder Compare against AD Domain

I'm trying to clean up our storage from legacy users that no longer exist and getting misc results.
I have a share with all usernames as folder names (ex. \\storage\homedir\joeblow) AD username: Joeblow. Throughout various years users have been removed from the domain but the folders were never removed from the share. So I am walking the share and using that to query the domain to find if said user still exists. I seems to work most the time and fail randomly. Not sure why, because manually sometimes the code will execute fine. Any thoughts?
Here is the code:
Import-Module ActiveDirectory
$folders = dir \\storage.domain.edu\C$\homedir3 | where {$_.PSIsContainer -eq $true}
$folder4 = "\\storage.domain.edu\C$\homedir4"
function New-Folder($Name, $Size) {
$folderList = New-Object PSObject
$folderList | Add-Member -MemberType NoteProperty -Name Name -Value $Name
$folderList | Add-Member -MemberType NoteProperty -Name Size -Value $Size
$folderList | Add-Member -MemberType NoteProperty -Name User -Value $User
}
foreach ($i in $folders) {
Write-Host "Folder presently is folder $i"
#$ADuser=Get-ADUser -Filter {$i.sAMAccountName.ToUpper() -eq"$i"} -SearchBase "OU=Active,OU=UserAccounts,DC=ad,DC=domain,DC=edu"
#$ADuser=Get-ADUser -Filter {samaccountname -eq $i} -SearchBase "OU=Active,OU=UserAccounts,DC=ad,DC=domain,DC=edu" -Property samaccountname
$r = "\\STORAGE.domain.EDU\HOMEDIR\$i"
$r = $r.ToUpper()
$ADuser = Get-ADUser -Filter {sameaccountname -eq $i} -SearchBase "OU=Active,OU=UserAccounts,DC=ad,DC=domain,DC=edu" -Property homeDirectory, samaccountname
if (!$ADuser) {
Write-Host "Null yo"
$ADuser = Get-ADUser -Filter {homeDirectory -eq $r} -SearchBase "OU=Active,OU=UserAccounts,DC=ad,DC=domain,DC=edu" -Property homeDirectory, samaccountname
}
$ADname = $ADuser.samaccountname.ToUpper()
$ADuser = $ADuser.homeDirectory
$ADuser = $ADuser.toupper()
Write-Host "R be this: $r and equal $ADuser"
#Write-Host "The person's folder name is: $ADuser"
#$iUp = $i.ToUpper()
Write-Host "The folder's is: $i"
if ($ADuser -eq $r) {
Write-Host "User: $ADname is in HomeDir3 $ADuser"
} else {
#(Test-Path "$folder4\$ADuser".trim()) {
#$notFound = $i
$folderList = New-Folder -Name $ADuser -User
Write-Host "$ADname failed"
}
}
#}
Write-Host "$folderList"
#$leftOvers = Compare-Object $folder4 $notFound
#Write-Host " Here is whats left $leftOvers"
#$i | Out-File -append "C:\deadaccounts.txt"

Powershell - Get-AdUser: Exclude users in array

I want to generate a list of users, with the exception of a list of names. This exclusion list changes from week to week.
$exclude = #('smith, bob', 'jones, tom', ...)
$csvmaster = #()
$uacct = 'User Account'
$UserID = 'User ID'
$lastname = 'Last Name'
... other attributes
$ulist = get-aduser -filter {enabled -eq 'true'} -properties * | ? {$_.Distinguishedname -like '*Standard User*' -and $_.title -ne $null -and $_.employeenumber -ne $null}
foreach ($u in $ulist)
{
if ($u.name -notmatch $exclude) {
$csvline = New-Object System.Object
$csvline | Add-Member -MemberType NoteProperty -name $UserID -value $u.EmployeeNumber
$csvline | Add-Member -MemberType NoteProperty -name $lastname -value $u.surname
...other attributes
$csvmaster += $csvline
}
}
...Output to csv
When I run this, the names I want to exclude still make it into the list. I also tried -notcontains and excluding them like this:
$ulist = get-aduser -filter {enabled -eq 'true'} -properties * | ? {$_.Distinguishedname -like '*Standard User*' -and $_.title -ne $null -and $_.employeenumber -ne $null -and $_.name -notmatch $exclude}
This behaves the same way.
Cheers.
So I think my problem was the way Get-ADUser accepts input value. And/Or my logic in general. I changed the code to this:
$exclude = #( ..list..of..names..)
$csvline = #()
$ulist = get-aduser ...
foreach ($u in $ulist)
{
if ($exclude -notcontains $u.name)
{
...
$csvline += $u.name
}
}
And it is doing what I need.

Powershell Script Truncated Result

I have the following script,
$filteracl = {$_.IdentityReference -match "User" -and ($_.FileSystemRights -band 131241 -or $_.FileSystemRights -band 278)}
$objects = Get-ChildItem "C:\" -Recurse -Force
foreach ($i in $objects)
{
$i.GetAccessControl().Access | Where $filteracl | Select `
#{n="Path";e={$i.fullname}},
#{n="User";e={$_.IdentityReference}},
#{n="Permission";e={$_.FileSystemRights}}
}
However, the output from the path is being truncated. I have no idea how to solve this.
Try Format-Table -Wrap like:
$filteracl = {$_.IdentityReference -match "User" -and ($_.FileSystemRights -band 131241 -or $_.FileSystemRights -band 278)}
$objects = Get-ChildItem "C:\" -Recurse -Force
foreach ($i in $objects)
{
$i.GetAccessControl().Access | Where $filteracl | Select `
#{n="Path";e={$i.fullname}},
#{n="User";e={$_.IdentityReference}},
#{n="Permission";e={$_.FileSystemRights}} |
Format-Table -Wrap
}
Since the whole statement is in a loop and Format-Table displays headers, so you'll see multiple headers. To get rid of that you can edit your script to store the output in an Array and then finally display when the loop is complete. Something like:
$filteracl = {$_.IdentityReference -match "User" -and ($_.FileSystemRights -band 131241 -or $_.FileSystemRights -band 278)}
$objects = Get-ChildItem "C:\" -Recurse -Force
$OutputView = #()
foreach ($i in $objects)
{
$s = $i.GetAccessControl().Access | Where $filteracl
$output = New-Object PSObject
$output | Add-Member -MemberType NoteProperty -Name "Path" -Value $i.fullname
$output | Add-Member -MemberType NoteProperty -Name "User" -Value $s.IdentityReference
$output | Add-Member -MemberType NoteProperty -Name "Permission" -Value $s.FileSystemRights
$OutputView += $output
}
$global:outputView |
Select-Object Path,User,Permission