none
How to get all AD User accounts, associated with any application/MSA/Batch Job running in a Local or Remote machine using Script (PowerShell) RRS feed

  • Question

  • Dear Scripting Guys,

    I am working in an AD migration project (Migration from old legacy AD domains to single AD domain) and in the transition phase. Our infrastructure contains lots of Users, Servers and Workstations. Authentication is being done through AD only. Many UNIX and LINUX based box are being authenticated through AD bridge to AD. 

    We have lot of applications in our environment. Many applications are configured to use Managed Service Accounts. Many Workstations and servers are running batch jobs with AD user credentials. Many applications are using AD user accounts to carry out their processes. 

    We need to find out all those AD Users, which are configured as MSA, Which are configured for batch jobs and which are being used for different applications on our network (Need to find out for every machine on network).

    These identified AD Users will be migrated to the new Domain with top priority. I get stuck with this requirement and your support will be deeply appreciated. I hope a well designed PS script can achieve this. 

    Thanks in advance...

    Thanks & Regards Bedanta S Mishra

    Thursday, April 30, 2015 7:54 AM

Answers

  • Hi Bedanta,

    There would be two ways of doing this:

    1. Going to each server and digging out , scheduled task, scripts, 3rd party programs for hidden user credentials which might be running regularly or maybe once every 3 months or as per user requirements.

    This option would be very tedious and not feasible in most cases (Like rarely used accounts).

    2. Use Active Directory "Audit account logon events" to locate the UserID, the Source who has succesfully logged in.

    I would say most of the active accounts (critical most likely) should be covered using this method. What you have to do is list out Succesful Logon Events for user accounts.

    NOTE:- Event IDs would vary depending on your DC version

    In addition to that, what I have seen is its best to reachout to project team\ managers to fetch as much details for any managed service accounts they are using. Doing this would give you additional cover up later, when they come back and say some account is not working anymore.(Which they didn't list out ofcouse initially) 

    HeadsUp on PowerShell script to filter the Eventlogs:

    Get-WinEvent -FilterHashtable @{logname='Security'; id=4624}
    Logon Events Description

    528

    A user successfully logged on to a computer. Windows Server 2003

    4624

    A user successfully logged on to a computer. Windows Server 2008\2012


    References:

    4624:        An account was successfully logged on

    Audit account logon events

    http://blogs.technet.com/b/heyscriptingguy/archive/2011/01/24/use-powershell-cmdlet-to-filter-event-log-for-easy-parsing.aspx


    Regards,

    Satyajit

    Please “Vote As Helpful” if you find my contribution useful or “Mark As Answer” if it does answer your question. That will encourage me - and others - to take time out to help you.

    • Proposed as answer by jrv Thursday, April 30, 2015 9:13 AM
    • Marked as answer by Boe ProxMVP, Moderator Sunday, July 26, 2015 3:32 AM
    Thursday, April 30, 2015 8:40 AM

All replies

  • Hi Bedanta,

    There would be two ways of doing this:

    1. Going to each server and digging out , scheduled task, scripts, 3rd party programs for hidden user credentials which might be running regularly or maybe once every 3 months or as per user requirements.

    This option would be very tedious and not feasible in most cases (Like rarely used accounts).

    2. Use Active Directory "Audit account logon events" to locate the UserID, the Source who has succesfully logged in.

    I would say most of the active accounts (critical most likely) should be covered using this method. What you have to do is list out Succesful Logon Events for user accounts.

    NOTE:- Event IDs would vary depending on your DC version

    In addition to that, what I have seen is its best to reachout to project team\ managers to fetch as much details for any managed service accounts they are using. Doing this would give you additional cover up later, when they come back and say some account is not working anymore.(Which they didn't list out ofcouse initially) 

    HeadsUp on PowerShell script to filter the Eventlogs:

    Get-WinEvent -FilterHashtable @{logname='Security'; id=4624}
    Logon Events Description

    528

    A user successfully logged on to a computer. Windows Server 2003

    4624

    A user successfully logged on to a computer. Windows Server 2008\2012


    References:

    4624:        An account was successfully logged on

    Audit account logon events

    http://blogs.technet.com/b/heyscriptingguy/archive/2011/01/24/use-powershell-cmdlet-to-filter-event-log-for-easy-parsing.aspx


    Regards,

    Satyajit

    Please “Vote As Helpful” if you find my contribution useful or “Mark As Answer” if it does answer your question. That will encourage me - and others - to take time out to help you.

    • Proposed as answer by jrv Thursday, April 30, 2015 9:13 AM
    • Marked as answer by Boe ProxMVP, Moderator Sunday, July 26, 2015 3:32 AM
    Thursday, April 30, 2015 8:40 AM
  • Hey Satyajit,

    Thank you for your valuable reply. It is really a great notion to enable account logon audit and collect those events for the analysis. But you know it is also a tedious job when thousand of Users come in to picture. You can imagine how complex it will be for this analysis, where more than 200000 users getting logged in through AD. It is the fact that when a batch / MS or an application uses a Domain Users credential with successful process, automatically a successful logon event will be triggered in associated DC. But there are also too many users which are not part of these accounts like MSA/Batch jobs or not linked to any application. In that case we have to get through unwanted events. 

    Recently jrv, provided me a beautiful script to find out all MSA from a machine or from a list of machines in an AD environment. (Covers MSA part.)

    $Report= 'Audit_Report.html'
    
    $Computers= Get-ADComputer -Filter 'Enabled -eq $True' | Select -Expand Name
    
    $head=@'
        <title>Non-Standard Service Accounts</title>
        <style>
        BODY{background-color :#FFFFF}
        TABLE{Border-width:thin;border-style: solid;border-color:Black;border-collapse: collapse;}
        TH{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color: ThreeDShadow}
        TD{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color: Transparent}
        </style>
    '@
    $sections=@()
    foreach($computer in $Computers){ 
            $sections+=Get-WmiObject -ComputerName $Computer -class Win32_Service -ErrorAction SilentlyContinue |
                Select-Object -Property StartName,Name,DisplayName |
                ConvertTo-Html -PreContent  "<H2>Non-Standard Service Accounts on '$Computer'</H2>" -Fragment 
        }
    $body=$sections | out-string
    ConvertTo-Html -Body $body -Head $head | Out-File $report
    Invoke-Item $report

    A script can be designed to get all scheduled back ground batch jobs in a machine, from which the author / the Owner of that scheduled job can be extracted. like below one...

    Function Get-ScheduledTasks
    {
    	Param
    	(
    		[Alias("Computer","ComputerName")]
    		[Parameter(Position=1,ValuefromPipeline=$true,ValuefromPipelineByPropertyName=$true)]
    		[string[]]$Name = $env:COMPUTERNAME
    		,
    		[switch]$RootOnly = $false
    	)
    	Begin
    	{
    		$tasks = @()
    		$schedule = New-Object -ComObject "Schedule.Service"
    	}
    	Process
    	{
    		Function Get-Tasks
    		{
    			Param($path)
    			$out = @()
    			$schedule.GetFolder($path).GetTasks(0) | % {
    				$xml = [xml]$_.xml
    				$out += New-Object psobject -Property @{
    					"ComputerName" = $Computer
    					"Name" = $_.Name
    					"Path" = $_.Path
    					"LastRunTime" = $_.LastRunTime
    					"NextRunTime" = $_.NextRunTime
    					"Actions" = ($xml.Task.Actions.Exec | % { "$($_.Command) $($_.Arguments)" }) -join "`n"
    					"Triggers" = $(If($xml.task.triggers){ForEach($task in ($xml.task.triggers | gm | Where{$_.membertype -eq "Property"})){$xml.task.triggers.$($task.name)}})
    					"Enabled" = $xml.task.settings.enabled
    					"Author" = $xml.task.principals.Principal.UserID
    					"Description" = $xml.task.registrationInfo.Description
    					"LastTaskResult" = $_.LastTaskResult
    					"RunAs" = $xml.task.principals.principal.userid
    				}
    			}
    			If(!$RootOnly)
    			{
    				$schedule.GetFolder($path).GetFolders(0) | % {
    					$out += get-Tasks($_.Path)
    				}
    			}
    			$out
    		}
    		ForEach($Computer in $Name)
    		{
    			If(Test-Connection $computer -count 1 -quiet)
    			{
    				$schedule.connect($Computer)
    				$tasks += Get-Tasks "\"
    			}
    			Else
    			{
    				Write-Error "Cannot connect to $Computer. Please check it's network connectivity."
    				Break
    			}
    			$tasks
    		}
    	}
    	End
    	{
    		[System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
    		Remove-Variable schedule
    	}
    }
    
    Get-ScheduledTasks -RootOnly | Format-Table -Wrap -Autosize -Property RunAs,ComputerName,Actions

    So I think, can a PS script be designed to get the report of all running applications which use domain accounts for their authentication to carry out their process. So from that result we can filter out the AD accounts being used for those applications. After that these three individual modules can be compacted in to a single script to provide the desired output as per the requirement in a single report.  

     


    Thanks & Regards Bedanta S Mishra



    Thursday, April 30, 2015 12:27 PM
  • These scripts are really powerful and would definetly provide you the data. But still would not cover you up fully.


    The script is listing all windows Services and accounts running them or scheduled task owner. But its not necessary that the applications are running as a service or scheduled tasks.
    Also the result would be inconsitent if the target computers are down or not reachable.

    Are you sure no-one is using there personal credentials to run the application, becasue I have seen this happening in many occasions, you will not figure this out until some daily task\reports stops suddenly the very next day someone leaves the org or you migrate that account in your case.

    Managed Service Accounts:
    Anyways if you are using \ concerned about the "Managed Service Accounts" only, then you are already down to the MSA accounts events instead of all 200000 users. Just filter out the data using "| where{} or a forloop maybe"


    All Managed Service Accounts are created (by default) in the new CN=Managed Service Accounts, DC=<domain>, DC=<com> container. You can see this by configuring DSA.MSC to show “Advanced Features”:


    Basically looking at your scale, you need to implement multiple overlapping solutions then consolidate the data to dedice on it. My earlier post being again one part of it.


    References:
    Few links that might help you out:

    Script - Get service account list from multiple remote servers
    Get-ADServiceAccount- To get managed service account information in AD DS

    Get-ADServiceAccount -Filter {HostComputers -eq "CN=SQL-Server-1, DC=contoso,DC=com" }



    Regards,

    Satyajit

    Please “Vote As Helpful” if you find my contribution useful or “Mark As Answer” if it does answer your question. That will encourage me - and others - to take time out to help you.

    Friday, May 1, 2015 8:06 AM
  • Dear Satyajit,

    My apology for the delay in reply... Thanks a lot for your valuable reply. 

    Yes, Many users are currently using their personal domain credentials for different applications, which is messy and before migration from legacy domains, we need to correct this structure. 

    You know, we can find the detail of installed application from local or remote machine. 

    Ref : https://gallery.technet.microsoft.com/scriptcenter/Get-RemoteProgram-Get-list-de9fd2b4

    The above script is great and I think if we can add a property that can give us the associated User Account with the applications, will solve the issue. 

    Dear Jrv,

    Need your notions please.


    Thanks & Regards Bedanta S Mishra

    Tuesday, May 5, 2015 9:26 AM