pixel0815
Goto Top

Powershell Skript - Find user who created an ad object

Hallo zusammen,

ich hab ein Script gefunden das mir eigentlich ganz gut gefällt, aber ich weiß nicht so recht was damit anzufangen.
Die Fragestellung ist recht simpel ( mache das bisher mit ADSI Editor ), ich möchte schauen wer ein AD Objekt angelegt hat.
Ich bekomme auch ein Output, aber ich möchte das so nutzen das mir das Skript das zeigt wenn ich z.B. eine Liste erstellt habe von Benutzern in den letzten zwei Wochen das mir dazu die Owner angezeigt werden.

http://blogs.msmvps.com/richardsiddaway/2012/02/17/find-user-who-create ...

function Resolve-SIDtoUser {            
 param ([byte[]]$sid)            
  $sb = New-Object -TypeName System.Text.StringBuilder            
              
  for ($i=0; $i -lt $sid.Length; $i++){            
   $sb.AppendFormat("\{0}",  $sid[$i].ToString("X2")) | Out-Null              
  }            
  $strsid = $sb.ToString()            
                
  $root = [ADSI]""              
  $search = [adsisearcher]$root            
  $search.Filter = "(objectSID=$strsid)"              
  $search.FindOne() | foreach {            
    return $_.Properties.name            
  }             
}            
            
$dom = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()            
$domain = $dom.GetDirectoryEntry()            
$dn = $($domain.distinguishedname)             
            
"`nMicrosoft"              
Get-ADObject -LDAPFilter "(mS-DS-CreatorSID=*)"  -Properties * |               
Format-Table ObjectClass, Name, DistinguishedName,             
@{N="Creator"; E={(Get-ADUser -Identity $($_."mS-DS-CreatorSID")).Name}} -AutoSize              
            
"`nAD provider"              
Get-ChildItem -Filter "(mS-DS-CreatorSID=*)" `  
-Path Ad:\$dn  -Recurse  | foreach {             
             
 $obj = [adsi]"LDAP://$($_.DistinguishedName)"              
             
 $user = Resolve-SIDtoUser $obj.Properties."mS-DS-CreatorSID".value              
              
 $obj | select  @{N="ObjectClass"; E={$_.SchemaClassName}},               
 @{N="Name"; E={$_.name}},               
 @{N="DistinguishedName"; E={$_.distinguishedname}},              
 @{N="Creator"; E={$user}}              
} | Format-Table -AutoSize            
            
"`nQuest"              
Get-QADObject -LDAPFilter "(mS-DS-CreatorSID=*)"  -IncludeAllProperties |               
Format-Table ClassName, Name, DistinguishedName,             
@{N="Creator"; E={(Get-QADUser -Identity $($_.CreatorSID)).Name}} -AutoSize              
            
"`nScript"              
$root = [ADSI]""              
$search = [adsisearcher]$root            
$search.Filter = "(mS-DS-CreatorSID=*)"               
$search.SizeLimit = 3000            
$search.FindAll() | foreach {            
             
 $obj = $_.GetDirectoryEntry()            
             
 $user = Resolve-SIDtoUser $obj.Properties."mS-DS-CreatorSID".value              
              
 $obj | select  @{N="ObjectClass"; E={$_.SchemaClassName}},               
 @{N="Name"; E={$_.name}},               
 @{N="DistinguishedName"; E={$_.distinguishedname}},              
 @{N="Creator"; E={$user}}              
 } | Format-Table -AutoSize

Gruß
Heiko

Content-Key: 269789

Url: https://administrator.de/contentid/269789

Printed on: April 16, 2024 at 20:04 o'clock

Member: colinardo
colinardo Apr 21, 2015 updated at 17:03:50 (UTC)
Goto Top
Hallo Heiko,
das Script kannst du für User nicht verwenden, wie im Posting schon steht wird das Attribut nur befüllt wenn ein User z.B. einen Computer zur Domain hinzufügt.
Bei Usern und anderen Objekten ist das Attribut normalerweise nicht gefüllt. Da wirst du das AD-Auditing einschalten müssen und den User aus dem Event-Log auslesen müssen welcher das jeweilige Objekt erstellt hat.

Wenn das Attribut beim User gefüllt wäre, sähe das gewünschte etwa so aus:
get-adobject -LDAPFilter "(&(ms-DS-CreatorSID=*)(objectClass=user))" -Properties * | ?{$_.Created -ge (get-date).AddDays(-14)} | select SamAccountName,Name, DistinguishedName, @{n='Creator';e={(get-aduser -Identity ($_.'ms-DS-CreatorSID')).Name}} | ft -Autosize  
Grüße Uwe
Member: pixel0815
pixel0815 Apr 22, 2015 updated at 06:35:02 (UTC)
Goto Top
Guten Morgen Uwe,

Mist. ich hab mir das schon gedacht. Warum macht MS das?
Ich würde mich ja schon zufrieden geben wenn man vernünftig den nTSecurityDescriptor-Owner eines AD Objekts auslesen könnte und in eine Darstellbare Form bringen kann so wie in diesem Beispiel von dem tollen Blog.
Wenn man mit delegierten Rechten im AD Arbeitet ist das ja ziemlich eindeutig wer den Benutzer erstellt hat.

Gruß
Heiko
Member: pixel0815
pixel0815 Apr 22, 2015 updated at 06:45:58 (UTC)
Goto Top
Gut, so zeigt mir die PS den Owner an.

$user = [ADSI](([ADSISearcher]"(SamAccountName=UserA)").FindOne().Path)  
$user.PsBase.ObjectSecurity.Owner

Würde das gehen das es so wäre, das z.B. die Benutzer der letzten 2 Wochen ausgegraben werden, den SamAccountName dann in so ein "Array" stecken, und die Abfrage dann for each user in users .. und dann noch mit ein paar mehr Infos wie erstellt am, erstellt von, in OU .. ausgegeben wird?
Member: pixel0815
pixel0815 Apr 22, 2015 at 07:01:48 (UTC)
Goto Top
Wie geil.. habe gerade das hier gefunden.
Wenn das jetzt noch den nTSecurityDescriptor-Owner mit ausgeben würde, wäre es perfekt :o) Ich glaub danach lecken sich bestimmt einige die Finger.

<#
.SYNOPSIS
	Simple email report of any new users that have been added to Active Directory
	in the past day.
.DESCRIPTION
	Script can be run via scheduled task and should have a repeat of the same time 
    frame you designate with the Age parameter.  IE if -Age is set to 30 days then 
    task should run every 30 days..  
	
	* Make sure to edit the PARAM section of the script to match your environment.
    * Edit the $Key variable in the Get-SavedCredential function
    
	Recommend you run from a Scheduled Task on a daily basis.  RSAT must be
	installed on the computer you are running this from.
    http://technet.microsoft.com/en-us/library/cc730825(v=ws.10).aspx
.PARAMETER Age
    Number of days to go back to search for new users.  Default is 1 day.
.PARAMETER To
	Email address of who will receive the email report
.PARAMETER From
	Email address of who you want to send the email.
.PARAMETER SMTPServer
	IP address or host name of your SMTP relay server
.PARAMETER UseCredential
	Use this parameter to specify you need to use credentials to send email. 
    
    Credentials are stored in an encrypted file in the same path as where the
    script is saved.  Make sure to edit the $Key variable below to give yourself
    a unique encryption key.
.PARAMETER UseSSL
    Specify if the script should use SSL when sending email
.PARAMETER Port
    Specify the port your SMTP relay server requires.  Default is port 25.
    If you specify UseSSL and do not specify a port the default SSL port will
    be 587.
.OUTPUTS
	Email with list of new users
.EXAMPLE
	.\Report-NewUsers.ps1
	Will accept all default parameters and send email report to "you@yourdomain.com".  
.EXAMPLE
	.\Report-NewUsers.ps1 -To myboss@yourcompany.com
	Will accept most default parameters, but override the TO address with 
	"myboss@yourcompany.com"  
.EXAMPLE
    .\Report-NewUsers.ps1 -Age 30 -To "myboss@yourcompany.com" -From "script@yourcompany.com" -SMTPServer "ExchangeServer1" -UseCredential   
    
    Will produce a report of all new user objects in the past 30 days, sending it to
    myboss@yourcompany.com via the ExchangeServer1 SMTP relay server.  The script will 
    prompt you for credentials the first time you run the script, but use the saved
    credential file from then on.  
.NOTES
    Author:             Martin Pugh
    Twitter:            @thesurlyadm1n
    Spiceworks:         Martin9700
    Blog:               www.thesurlyadmin.com
       
    Changelog:
        1.1             Updated Get-SavedCrential function to latest version.  Added a 
                        configurable duration to scan for new user objects.  Updated the
                        report to send an HTML style report instead of text.  Updated
                        email sending capability to allow sending to all kinds of email
                        servers including GMail.  
                        *New version requires PowerShell 3.0
        1.0             Initial Release

.LINK
    http://community.spiceworks.com/scripts/show/1647-email-daily-report-of-new-users
#>
#requires -version 3.0
Param (
    [int]$Age = 1,
	[string]$To = "email",  
	[string]$From = "email",  
	[string]$SMTPServer = "adresser",  
	[switch]$UseCredential,
    [switch]$UseSSL,
    [int]$Port = 25
)
	
Function Get-SavedCredential {
	<#
	.SYNOPSIS
		Simple function to get and save domain credentials.
	.LINK
		http://community.spiceworks.com/scripts/show/1629-get-secure-credentials-function
	#>
    Param (
	    [String]$AuthUser = $env:USERNAME,
        [string]$PathToCred
    )
    $Key = [byte]29,36,18,74,72,75,85,52,73,44,0,21,98,76,99,28

    #Build the path to the credential file
    $CredFile = $AuthUser.Replace("\","~")  
    $File = $PathToCred + "\Credentials-$CredFile.crd"  
	#Find encrypted credential file, if not there create it
    If (-not (Test-Path $File))
	{	(Get-Credential $AuthUser).Password | ConvertFrom-SecureString -Key $Key | Set-Content $File
    }
	#Load the credential file 
    $Password = Get-Content $File | ConvertTo-SecureString -Key $Key
    $AuthUser = (Split-Path $File -Leaf).Substring(12).Replace("~","\")  
    $AuthUser = $AuthUser.Substring(0,$AuthUser.Length - 4)
	$Credential = New-Object System.Management.Automation.PsCredential($AuthUser,$Password)
    Return $Credential
}

Try { Import-Module ActiveDirectory -ErrorAction Stop }
Catch { Write-Host "Unable to load Active Directory module, is RSAT installed?" -ForegroundColor Red; Exit }  

#Find users that have been created in the past day
$Then = (Get-Date).AddDays(-$Age).Date
$Users = Get-ADUser -Filter { whenCreated -ge $Then } -Properties whenCreated

#Create hashtable with SMTP settings
If ($UseSSL -and $Port -eq 25)
{   $Port = 587
}

$SMTPProperties = @{
	From = $From
	To = $To
	Subject = "New Users created since $Then"  
	SMTPServer = $SMTPServer
    UseSSL = $UseSSL
    Port = $Port
}
If ($UseCredential)
{   $Path = Split-Path ((Get-PSCallStack).ScriptName)
    $SMTPProperties.Add("Credential",(Get-SavedCredential -PathToCred $Path))  
}

$Header = @"  
<style>
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
</style>
"@  

#Create the email body with user names
If ($Users)
{	$Pre = "<p><h3>Es wurden $($Users.Count) user objects erstellt seit $Then</h3></p><br>"  
	$Body = $Users | Select SamAccountName,Name,whenCreated,DistinguishedName | Sort whenCreated | ConvertTo-HTML -PreContent $Pre -Head $Header | Out-String
}
Else
{	$Body = "<br>Keine neuen Benutzer erstellt seit $Then."  
}

Try {
    Send-MailMessage @SMTPProperties -Body $Body -BodyAsHtml -ErrorAction Stop
}
Catch {
    $Users | Select SamAccountName,Name,whenCreated,DistinguishedName | Format-Table -AutoSize
    Write-Host "Unable to send email because: $($Error)" -ForegroundColor Red  
}
Member: colinardo
Solution colinardo Apr 22, 2015 updated at 08:27:50 (UTC)
Goto Top
Moin,
wer weckt mich hier aus dem Schlaf des gerechten face-wink Bin gerade erst vom anderen Ende der Welt zurück in "good old germany" und schlafe meinen Jetlag aus face-wink

Wenn das jetzt noch den nTSecurityDescriptor-Owner mit ausgeben würde, wäre es perfekt :o) Ich glaub danach lecken sich bestimmt einige die Finger.
Das ist dann wohl das geringste Problem...
<#
.SYNOPSIS
	Simple email report of any new users that have been added to Active Directory
	in the past day.
.DESCRIPTION
	Script can be run via scheduled task and should have a repeat of the same time 
    frame you designate with the Age parameter.  IE if -Age is set to 30 days then 
    task should run every 30 days..  
	
	* Make sure to edit the PARAM section of the script to match your environment.
    * Edit the $Key variable in the Get-SavedCredential function
    
	Recommend you run from a Scheduled Task on a daily basis.  RSAT must be
	installed on the computer you are running this from.
    http://technet.microsoft.com/en-us/library/cc730825(v=ws.10).aspx
.PARAMETER Age
    Number of days to go back to search for new users.  Default is 1 day.
.PARAMETER To
	Email address of who will receive the email report
.PARAMETER From
	Email address of who you want to send the email.
.PARAMETER SMTPServer
	IP address or host name of your SMTP relay server
.PARAMETER UseCredential
	Use this parameter to specify you need to use credentials to send email. 
    
    Credentials are stored in an encrypted file in the same path as where the
    script is saved.  Make sure to edit the $Key variable below to give yourself
    a unique encryption key.
.PARAMETER UseSSL
    Specify if the script should use SSL when sending email
.PARAMETER Port
    Specify the port your SMTP relay server requires.  Default is port 25.
    If you specify UseSSL and do not specify a port the default SSL port will
    be 587.
.OUTPUTS
	Email with list of new users
.EXAMPLE
	.\Report-NewUsers.ps1
	Will accept all default parameters and send email report to "you@yourdomain.com".  
.EXAMPLE
	.\Report-NewUsers.ps1 -To myboss@yourcompany.com
	Will accept most default parameters, but override the TO address with 
	"myboss@yourcompany.com"  
.EXAMPLE
    .\Report-NewUsers.ps1 -Age 30 -To "myboss@yourcompany.com" -From "script@yourcompany.com" -SMTPServer "ExchangeServer1" -UseCredential   
    
    Will produce a report of all new user objects in the past 30 days, sending it to
    myboss@yourcompany.com via the ExchangeServer1 SMTP relay server.  The script will 
    prompt you for credentials the first time you run the script, but use the saved
    credential file from then on.  
.NOTES
    Author:             Martin Pugh
    Twitter:            @thesurlyadm1n
    Spiceworks:         Martin9700
    Blog:               www.thesurlyadmin.com
       
    Changelog:
        1.1             Updated Get-SavedCrential function to latest version.  Added a 
                        configurable duration to scan for new user objects.  Updated the
                        report to send an HTML style report instead of text.  Updated
                        email sending capability to allow sending to all kinds of email
                        servers including GMail.  
                        *New version requires PowerShell 3.0
        1.0             Initial Release

.LINK
    http://community.spiceworks.com/scripts/show/1647-email-daily-report-of-new-users
#>
#requires -version 3.0
Param (
    [int]$Age = 1,
	[string]$To = "email",  
	[string]$From = "email",  
	[string]$SMTPServer = "adresser",  
	[switch]$UseCredential,
    [switch]$UseSSL,
    [int]$Port = 25
)
	
Function Get-SavedCredential {
	<#
	.SYNOPSIS
		Simple function to get and save domain credentials.
	.LINK
		http://community.spiceworks.com/scripts/show/1629-get-secure-credentials-function
	#>
    Param (
	    [String]$AuthUser = $env:USERNAME,
        [string]$PathToCred
    )
    $Key = [byte]29,36,18,74,72,75,85,52,73,44,0,21,98,76,99,28

    #Build the path to the credential file
    $CredFile = $AuthUser.Replace("\","~")  
    $File = $PathToCred + "\Credentials-$CredFile.crd"  
	#Find encrypted credential file, if not there create it
    If (-not (Test-Path $File))
	{	(Get-Credential $AuthUser).Password | ConvertFrom-SecureString -Key $Key | Set-Content $File
    }
	#Load the credential file 
    $Password = Get-Content $File | ConvertTo-SecureString -Key $Key
    $AuthUser = (Split-Path $File -Leaf).Substring(12).Replace("~","\")  
    $AuthUser = $AuthUser.Substring(0,$AuthUser.Length - 4)
	$Credential = New-Object System.Management.Automation.PsCredential($AuthUser,$Password)
    Return $Credential
}

Try { Import-Module ActiveDirectory -ErrorAction Stop }
Catch { Write-Host "Unable to load Active Directory module, is RSAT installed?" -ForegroundColor Red; Exit }  

#Find users that have been created in the past day
$Then = (Get-Date).AddDays(-$Age).Date
$Users = Get-ADUser -Filter { whenCreated -ge $Then } -Properties whenCreated | select *,@{n='Creator';e={$user = [ADSI](([ADSISearcher]"(SamAccountName=$($_.SamAccountName))").FindOne().Path);$user.PSBase.ObjectSecurity.Owner.ToString()}}  

#Create hashtable with SMTP settings
If ($UseSSL -and $Port -eq 25)
{   $Port = 587
}

$SMTPProperties = @{
	From = $From
	To = $To
	Subject = "New Users created since $Then"  
	SMTPServer = $SMTPServer
    UseSSL = $UseSSL
    Port = $Port
}
If ($UseCredential)
{   $Path = Split-Path ((Get-PSCallStack).ScriptName)
    $SMTPProperties.Add("Credential",(Get-SavedCredential -PathToCred $Path))  
}

$Header = @"  
<style>
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #6495ED;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
</style>
"@  

#Create the email body with user names
If ($Users)
{	$Pre = "<p><h3>Es wurden $($Users.Count) user objects erstellt seit $Then</h3></p><br>"  
	$Body = $Users | Select SamAccountName,Name,whenCreated,DistinguishedName,Creator | Sort whenCreated | ConvertTo-HTML -PreContent $Pre -Head $Header | Out-String
}
Else
{	$Body = "<br>Keine neuen Benutzer erstellt seit $Then."  
}

Try {
    Send-MailMessage @SMTPProperties -Body $Body -BodyAsHtml -ErrorAction Stop
}
Catch {
    $Users | Select SamAccountName,Name,whenCreated,DistinguishedName,Creator | Format-Table -AutoSize
    Write-Host "Unable to send email because: $($Error)" -ForegroundColor Red  
}