Powershell script to confirm an account from a CSV is disabled before deleting the account - active-directory

Hi I hope someone can help me, I'm not great at scripting and my issue is...
I have a medium estate of around 15,000 users which is in a bit of a mess. There are around 3000 user accounts which are disabled. Some user accounts are disabled due to the user being on long term sick, maternity, or suspended, these 'known' accounts are not to be touched so I cannot do a broad "find accounts that are disabled and just delete them" script.
Currently I have a script which exports all disabled accounts to a csv, I then manually manipulate that data within the csv to tag known accounts that cannot be deleted. I then take that file and run this script...
Import-Module ActiveDirectory
$list = Import-CSV C:\temp\deleteuser.csv
forEach ($item in $list) {
$samAccountName = $item.samAccountName
#Get DistinguishedName from SamAccountName
$DN = Get-ADuser -Identity $Samaccountname -Properties DistinguishedName |
Select-Object -ExpandProperty DistinguishedName
try{
#Remove object using DN
Remove-ADObject -Identity $DN -Confirm:$false
"Remove successful for $SamAccountName" | Out-File 'C:\temp\Account Delete Success.txt' -Append }
Catch{
"Remove failed for $SamAccountName" | Out-File 'C:\temp\Account Delete Failed.txt' -Append
}
}
While this is great, I'd love to be able to check the user account is still disabled before the Remove-ADObject command is run and for it to skip the account and output the name of the skipped account to a txt file. Is that possible or am I over complicating things?

simply test 'Enabled' property before deleting user like this :
Import-Module ActiveDirectory
$list = Import-CSV C:\temp\deleteuser.csv
forEach ($item in $list) {
$samAccountName = $item.samAccountName
#Get DistinguishedName from SamAccountName
$DN = Get-ADuser -Identity $Samaccountname -Properties DistinguishedName, Enabled |
Select-Object -ExpandProperty DistinguishedName
try{
#Remove object using DN
if (!$DN.Enabled){
Remove-ADObject -Identity $DN -Confirm:$false
"Remove successful for $SamAccountName" | Out-File 'C:\temp\Account Delete Success.txt' -Append }
else {
"Remove aborted for $SamAccountName" | Out-File 'C:\temp\Account Delete aborted.txt' -Append }
}
}
Catch{
"Remove failed for $SamAccountName" | Out-File 'C:\temp\Account Delete Failed.txt' -Append
}
}

Related

Powershell iterate through server list with credentials

I've been lurking around grabbing code answers from this site for years, but this is my first time actually asking a question. I don't actually get paid to code, rather I use scripts to make routine tasks easier.
I've been using a powershell script with the following code (that I pretty much gleaned from this site) to gather disk usage on client servers:
$dataColl = #()#Makes an array, or a collection to hold all the object of the same fields
foreach ($serverName in (get-content c:\reporting\Disk_useage\My_servers.txt))
{
$path = “\\$serverName\d$\folder1\TargetSubdir“
$dirSize = Get-ChildItem $path -recurse -force | select Length |Measure-Object -Sum length
$dirSize.sum = $dirSize.sum/1MB
$finalResult = “{0:N2} MB” -f $dirsize.sum
$dataObject = New-Object PSObject
Add-Member -inputObject $dataObject -memberType NoteProperty -name “ServerName” -value $serverName
Add-Member -inputObject $dataObject -memberType NoteProperty -name “Dir_Size” -value $finalResult
$dataColl += $dataObject
$dataObject
}
$dataColl | Export-Csv -noTypeInformation -path c:\reporting\Disk_useage\Svr_disk.csv
This has been working fine, but we now have a 2nd domain with client servers, so I need to add credentials for servers in the 2nd domain. I've been researching ways to pass credentials along, and got this bit of code (PW has been stored already in the .TXT file):
$username = "MyDomain\MyAccount"
$password = cat C:\reporting\securestring.txt | convertto-securestring
$cred = new-object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
But I'm supposed to add these parameters somewhere to actually USE the credentials that have been set up:
-Authentication default -Credential $Cred
I've tried it in several different spots without success. FYI, the list in My_servers.txt has a bunch of servers I DON'T need credentials for (since they're on the current domain), and a bunch of servers where I DO need credentials (because they're on another domain). But the credentials I'm using for the script are for a service account that exists in both domains with the same ID/PW. Any help in sorting this out would be greatly appreciated.
Adil's suggestion in code would be:
$dataColl = #()#Makes an array, or a collection to hold all the object of the same fields
$username = "MyDomain\MyAccount"
$password = Get-Content C:\reporting\securestring.txt | convertto-securestring
$cred = New-Object -typename System.Management.Automation.PSCredential `
-argumentlist $username, $password
foreach ($serverName in (get-content c:\reporting\Disk_useage\My_servers.txt))
{
$dirSize = Invoke-Command -Credential $cred -ComputerName $serverName -ScriptBlock {
Get-ChildItem “d:\folder1\TargetSubdir“ -recurse -force | select Length | Measure-Object -Sum length
}
$dirSize.sum = $dirSize.sum/1MB
$finalResult = “{0:N2} MB” -f $dirsize.sum
$dataObject = New-Object PSObject
Add-Member -inputObject $dataObject -memberType NoteProperty -name “ServerName” -value $serverName
Add-Member -inputObject $dataObject -memberType NoteProperty -name “Dir_Size” -value $finalResult
$dataColl += $dataObject
$dataObject
}
$dataColl | Export-Csv -noTypeInformation -path c:\reporting\Disk_useage\Svr_disk.csv

Passing an array to Get-Job

I am having trouble getting an array passed to a scriptblock in Start-Job. Can you tell me what I might be doing wrong?
$bounceBlock = {
param(
[string[]]$list,
[System.Management.Automation.PSCredential]$cred
)
Add-PSSnapin VMware.VimAutomation.Core | Out-Null
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Scope User -InvalidCertificateAction Ignore -Confirm:$false | Out-Null
Connect-VIServer -Server servername -Credential $cred -AllLinked
Get-VM -Name $list
}
if ($targets) {
$activeTargets = $targets | Get-Random -Count $prodTargets.Count
$counter = [pscustomobject] #{Value = 0}
$groupSize = 50
$groups = $activeTargets | Group-Object -Property {[math]::Floor($counter.Value++ / $groupSize)}
$connection = Connect-VIServer -Server servername -Credential $cred -AllLinked
if ($connection -match "servername") {
foreach ($group in $groups) {
while ((Get-Job -State Running).Count -ge 5) {
Start-Sleep -Seconds 5
}
Start-Job -ScriptBlock $bounceBlock -ArgumentList (,$group.Group.ServerName),$cred
}
Disconnect-VIServer * -Force -Confirm:$false
}
}
I basically split an array into chunks of 50 (working) then try to run them as jobs. The error I get looks like it's trying to run Get-VM for a single server, named all 50 values appended together.
I am certainly no expert with PS, but first to address how you're passing in the appended list of servers; I do something similar with Azure VMs using Get-AzureVM and I pass in my list of VM names in a System.Array to functions or cmdlets such as a variable such as $theVMs= "MyServer1","MyServer2","MyServer3"
and then I execute a foreach loop over ($vm in $theVMs) and then perform the actions such as Get-VM sequentially. I do this sequentially since PS has some much lower limits, 5 per my experience, doing this via a parallel for loop.
A typical way I interact with the VMs remotely and create a PS Job per each is to use
$uri = Get-AzureWinRMUri -ServiceName $svc -Name $vmname
Invoke-Command -ConnectionUri $uri -Credential $creds **-JobName
$jobname**
-ArgumentList $vmname -ScriptBlock {
param([string]$thevm) ...
}
This requires the InstallWinRMCertAzureVM.ps1 script which is discussed and available at http://blogs.technet.com . I use this for between 30 servers regularly.
Just wanted everyone to know in case they run into a similar problem, this is an issue with running Get-VM, and it exists whether running it in a job or workflow. VMWare is aware of this issue.

How can I initialize the names in this loop and create the parameter?

param(
[string]$UserName
)
$DCs = Get-ADGroupMember "Domain Controllers"
foreach ($DC in $DCs)
{
Write-Host $DC.name
}
$EventList = Get-Eventlog –ComputerName $ComputerName -LogName Security -InstanceID 4740 -UserName *Username* -After "07/20/2014"
$EventList | Format-List -Property TimeGenerated,Message
I'm writing a script to figure out lockout events for specific users within all the domains.
I'm trying to figure out how to the computername variable from the $DC.name, I know at some point i'll have to move the $Eventlist = Get-Eventlog line within the loop.Then would I just delete the write-host $DC.name?
Get-EventLog can take an array of computernames. You don't even need the foreach loop. So what you could do is this:
$DCs = Get-ADGroupMember "Domain Controllers"
$EventList = Get-Eventlog –ComputerName $DCs.Name -LogName Security -InstanceID 4740 -UserName *Username* -After "07/20/2014"
$EventList | Format-List -Property TimeGenerated,Message
Note that you should only use Format-List if you do not intend to use the information for anything other than displaying in the console. If you want to use the object for anything, don't use Format-List or Format-Table.

How to find the client name who has logged in to machine?

We are trying to find from which machine a user has taken rdp .
Using "quser" utility we are able to get all the information about logged in user except client name.
Following is the command
function Get-LoggedOnUser
{
param([String[]]$ComputerName = $env:COMPUTERNAME)
$ComputerName | ForEach-Object {
(quser /SERVER:$_) -replace '\s{2,}', ',' |
ConvertFrom-CSV |
Add-Member -MemberType NoteProperty -Name ComputerName -Value $_ -PassThru
}
}
It displays all the information which can be provided in Windows task manager except client Name .
How to get client Name using powershell?
I doubt if WMI has a way to do this. You can check the PSTerminal Services module and it has a Get-TSSession cmdlet which does the same job you are looking for.
http://archive.msdn.microsoft.com/PSTerminalServices
This module uses binary Cassia namespace.
You can use this:
http://gallery.technet.microsoft.com/scriptcenter/0e43993a-895a-4afe-a2b2-045a5146048a
and look for the logged on user with a logon type of RemoteInteractive
You can read that information from the Security eventlog (look for logon type 10):
$username = '...'
$eventID = 4624 # 526 on Server 2003 and earlier
$date = (Get-Date).Date
$pattern = 'logon type:\s+10[\s\S]+source network address:\s+(\S+)'
Get-EventLog Security -InstanceId $eventID -EntryType SuccessAudit `
-After $date -Message '*$username*' `
| ? { $_.Message -match $pattern } `
| % { $matches[1] } `
| select -Unique
Note that on Server 2003 and earlier you need to check for event ID 528 instead of 4624.
References:
http://technet.microsoft.com/en-us/library/cc787567
http://support.microsoft.com/kb/977519

How to populate other attributes when using powershell 2.0 new-aduser?

When trying to create users from a file I get an error when -otherAttributes #{} is added to ps script. I am new to powershell and can not get it to work. Any guidance is appreciated. This is My code:
Import-Module ActiveDirectory
$OU = 'ou=Staging OU, dc=Domain, dc=net'
$usrfile = "\\servername\testuser.csv"
Import-Csv $usrfile |
ForEach-Object {
New-ADUser -SamAccountName $_.samaccountname -UserPrincipalName $_.Userprincipalname -Name $_.Name -DisplayName $_.displayname -GivenName $_.givenname -Surname $_.sn -Initials $_.initials -Title $_.title -OtherName $_.middlename `
-Description $_.description -Department $_.department -EmployeeID $_.employeeid -Path $OU -Country $_.c `
-OtherAttributes #{departmentNumber=$user.departmentnumber;localeID=$user.localid;extensionAttribute1=$user.extensionAttribute1;employeeType=$user.employeetype} `
-AccountPassword (ConvertTo-SecureString "Password" -AsPlainText -Force) -Enabled $true `
-PasswordNeverExpires $false -ChangePasswordAtLogon $true -PassThru
} > Import.log
The parameter "-otherAttributes #{}" fails in my AD. I found other way change this value in AD.
Try with this:
PS> Set-ADuser -identity joseiba -Clear 'msRTCSIP-PrimaryUserAddress'
PS> Set-ADuser -identity joseiba -Add #{'msRTCSIP-PrimaryUserAddress'='4213#grupofibratel.com'}
BR
Make sure you have all your $'s as $_... when accessing the object in the current loop iteration. I see some aren't.
you left out your ' around the ldapdisplayname for the otherattributes
#{departmentNumber=$user.departmentnumber;
should be: #{'departmentNumber'=$user.departmentnumber;
you need the ' around each ldapdisplayname in otherattributes..
just fought this myself dealing with the notes field

Resources