PSAdsi.psm1
# ipmo .\RDS.DragonFly.psd1 -Force; rds LOGEXI@OPEN.ADDS # https://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx function Get-AllADs { <# .SYNOPSIS Liste toutes le Foret accessible .DESCRIPTION [Descriptif en quelques lignes] .EXAMPLE Get-AllADs .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> begin { } process { if (!$global:ADs){ $global:ADs = @() try { $global:ADs += ([System.DirectoryServices.ActiveDirectory.Domain]::getCurrentDomain()).Forest.name $global:ADs += ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().GetAllTrustRelationships()).targetName $global:ADs += ([System.DirectoryServices.ActiveDirectory.Domain]::getCurrentDomain().GetAllTrustRelationships()).targetName } catch { Write-LogStep 'Chargement [Domain-Forest] ',$_ error } [array]::sort($global:ADs) } } end { return $global:ADs } } function Get-ADSIGroup { <# .SYNOPSIS liste tous les Groups qui correcponde a un pattern .DESCRIPTION recherche dans toute les AD .PARAMETER NtAccountName pattern de recherche .EXAMPLE Get-ADSIGroup 'MyDomain\Groupe *' .EXAMPLE 'Groupe *@Domain.tld' | Get-ADSIGroup .EXAMPLE Get-ADSIGroup 'Groupe admin@*.tld' .EXAMPLE Get-ADSIGroup '*\*' .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)]$NtAccountName ) begin { $Searcher = New-Object DirectoryServices.DirectorySearcher } process { foreach ($Item in $NtAccountName) { if($item -like '*\*'){ $domain,$SamAccountName = $item.split('\') } elseif($item -like '*@*') { $SamAccountName,$domain = $item.split('@') $domain=$domain.Split('.')[0] } else { $SamAccountName = $item $domain = '*' } $Searchroot = (Get-AllADs) -like "$domain.*" $Searcher.Filter = "(objectCategory=group)" if($SamAccountName) { $Searcher.Filter = "(&(objectCategory=group)(samAccountName=$SamAccountName))" } # (&(objectClass=group)(email=*)) foreach($AD in $Searchroot){ $Searcher.SearchRoot = "LDAP://$($AD -replace('^(.+)\.(.+)$','DC=$1,DC=$2'))" try { $Searcher.FindAll() | ?{$_} # | ForEach-Object {[adsi]$_.path}).Properties Write-LogStep "Collecte ADSI [$AD]",$samAccountName ok } catch { Write-LogStep "Collecte ADSI [$SamAccountName@$AD]",$_ error } } } } end {} } function Get-ADSIUser { <# .SYNOPSIS liste tous les Users d'une par le ntaccountName .DESCRIPTION Retoune tous les Objet ADSI Users d'un ensemble d'OU et qui .PARAMETER NtAccountName pattern de recherche .EXAMPLE Get-ADSIUser (whoami) .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)]$NtAccountName ) begin { $Searcher = New-Object DirectoryServices.DirectorySearcher } process { foreach ($Item in $NtAccountName) { if($item -like '*\*'){ $domain,$SamAccountName = $item.split('\') } elseif($item -like '*@*') { $SamAccountName,$domain = $item.split('@') $domain=$domain.Split('.')[0] } else { $SamAccountName = $item $domain = '*' } $Searchroot = (Get-AllADs) -like "$domain.*" $Searcher.Filter = "(objectCategory=user)" if($SamAccountName) { $Searcher.Filter = "(&(objectCategory=user)(samAccountName=$SamAccountName))" } # (&(objectClass=user)(email=*)) foreach($AD in $Searchroot){ $Searcher.SearchRoot = "LDAP://$($AD -replace('^(.+)\.(.+)$','DC=$1,DC=$2'))" try { $Searcher.FindAll() | ?{$_} # | ForEach-Object {[adsi]$_.path}).Properties Write-LogStep "Collecte ADSI [$AD]",$samAccountName ok } catch { Write-LogStep "Collecte ADSI [$SamAccountName@$AD]",$_ error } } } } end {} } function Set-ADSIPassword { <# .SYNOPSIS [Descriptif en quelques mots] .DESCRIPTION [Descriptif en quelques lignes] .PARAMETER NtAccountName .EXAMPLE Set-ADSIPassword .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)]$NtAccountName ) begin {} process { $NtAccountName | Get-ADSIUser | %{ # $dataObject = New-Object Windows.forms.DataObject $login = $($_.properties.userprincipalname) -replace ('(.+)@(.+)\..+', '$2\$1') try { $Cred = Get-Credential -Message "Definir un nouveau Mdp.`r`nValider a Vide, pour generer automatiqument d'apres la stategie RGPD" -UserName $login $mdp = $Cred.GetNetworkCredential().Password if(!$mdp){ # validé a vide $lesspass = $cred.UserName | Update-LessPassword [System.Windows.Forms.Clipboard]::SetDataObject($lesspass.Password, $true) Invoke-BalloonTip -Title 'Set LessPassword' -Message "Mdp [$($lesspass.NtAccountName)] dans le Press-Papier" -Type Info } else { # valide mdp Manuel ([ADSI]$_.Path).setpassword($mdp) [System.Windows.Forms.Clipboard]::SetDataObject($mdp, $true) Invoke-BalloonTip -Title 'Set Password Manuel' -Message "Mdp [$($cred.UserName)] dans le Press-Papier" -Type Info } } catch [System.Runtime.InteropServices.ExternalException] { # echec Invoke-BalloonTip -Title 'Update Password' -Message "Mdp [$($cred.UserName)] dans le Press-Papier" -Type Error Write-LogStep -prefix "L.$($_.InvocationInfo.ScriptLineNumber)" "Change Mdp ",$_ error } catch { # Abandon Write-LogStep -prefix "L.$($_.InvocationInfo.ScriptLineNumber)" "Change Mdp ",$_ error } } } end {} } function Set-AdsiProperties { <# .SYNOPSIS [Descriptif en quelques mots] .DESCRIPTION [Descriptif en quelques lignes] .PARAMETER AdsiItems .PARAMETER ExtraParameters .EXAMPLE Set-AdsiProperties .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> param ( [Parameter(ValueFromPipeline = $true)] $AdsiItems = $null, [Parameter(ValueFromRemainingArguments=$true)]$ExtraParameters ) begin { $Properties = @{} $UnnamedParams = @() $Name = $null $ExtraParameters | ForEach-Object -Process { if ($_ -match "^-") { if ($Name) { $Properties.$Name = $true } $Name = $_ -replace "^-|:$" } else { if ($Name) { $Properties.$Name += $_ $Name = $null } else { $UnnamedParams += $_ } } } -End { if ($Name) { $Properties.$Name = $true } } $properties | Write-Object -back black -fore Yellow } process { foreach ($item in $AdsiItems) { if ($item -is [System.DirectoryServices.SearchResult]) { $item = [adsi]$item.path } # elseif ($item -is [string]) { # if ($item -match '^LDAP:\/\/CN=(.+),(OU=([\w\d\s_-]+))*,DC=([\w\d\s_-]+),DC=(com|adds)$') { # $item = [adsi]$item # } elseif ($item -match '^CN=(.+),(OU=([\w\d\s_-]+))*,DC=([\w\d\s_-]+),DC=(com|adds)$') { # $item = [adsi]"LDAP://$item" # } elseif ($item -match '^S-1-5-21-') { # $item = [adsi]"LDAP://<SID=$item>" # } else { if ($item -isnot [System.DirectoryServices.DirectoryEntry]) { # Write-LogStep "Format de parametre","[ADSI] required !" error break; # } } # $Item.Properties | ft * # %{$_.PropertyName;$_.Value} try { foreach ($Property in $Properties.GetEnumerator()) { $Item.Properties.($Property.name) | Write-Object -back black -fore Yellow $Property | Write-Object -back black -fore Cyan $Item.Put($Property.name, @($Property.Value)) $Item.SetInfo() } Write-LogStep "Mofification ",$Property.keys ok } catch { Write-LogStep -prefix "L.$($_.InvocationInfo.ScriptLineNumber)" "Mofification [$($Property.name)]",$_ Error } } } end {} } Function Get-ADSIMemberOf{ <# .SYNOPSIS [Descriptif en quelques mots] .DESCRIPTION [Descriptif en quelques lignes] .PARAMETER ADSIObject .PARAMETER Groups .PARAMETER Recurse .EXAMPLE Get-ADSIMemberOf .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> Param( [Parameter(ValueFromPipeline=$true)]$ADSIObject, $Groups = $null, [switch]$Recurse ) begin { } process { # Write-verbose $ADSIObject.Path if($null -eq $Groups){ $Groups = [PSCustomObject]@{ MemberOf = @() NestedMemberOf = @() } Foreach($Memberof in $ADSIObject.properties.memberof){ $Group = [adsi]"LDAP://$MemberOf" $Groups.Memberof += $group if($Group.properties.memberof -and $Recurse){ $Groups = $group | Get-ADSIMemberOf -Groups $Groups -Recurse } } } else { Foreach($Memberof in $ADSIObject.properties.memberof){ $path = "LDAP://$MemberOf" if($Groups.MemberOf.path -contains $path){ # write-verbose "Deja [DirectMemberOf] $path" }elseif($Groups.NestedMemberOf.path -contains $path){ # write-verbose "Deja [NestedMemberOf] $path" } else { # write-verbose "Nouveau [NestedMemberOf] $path" $Group = [adsi]$path $Groups.NestedMemberof += $group $Groups = $group | Get-ADSIMemberOf -Groups $Groups -Recurse } } } # Write-Object $Groups.memberOf.Path -Depth 1 -backGroundColor Black -foreGroundColor darkGreen # Write-Object $Groups.NestedMemberOf.Path -Depth 1 -backGroundColor Black -foreGroundColor Green $Groups } end { } } function Get-ADSIComputer { <# .SYNOPSIS liste tous les Ordineteur d'une OU .DESCRIPTION Retoune tous les Objet ADSI Ordinateur d'un ensemble d'OU et qui .PARAMETER Searchroot liste des DistingishedName a parcourir .PARAMETER ComputerName pattern de recherche .EXAMPLE Get-ADSIGroup .NOTES Alban LOPEZ 2019 alban.lopez@gmail.com http://git/PowerTech/ #> [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)]$ComputerName ) begin { $Searcher = New-Object DirectoryServices.DirectorySearcher } process { foreach ($Item in $ComputerName) { if($item -like '*\*'){ $domain,$name = $item.split('\') } elseif($item -like '*@*') { $name,$domain = $item.split('@') $domain=$domain.Split('.')[0] } else { $name = $item $domain = '*' } $Searchroot = @((Get-AllADs) -like "$domain.*") $Searcher.Filter = "(objectCategory=computer)" if($name) { $Searcher.Filter = "(&(objectCategory=computer)(name=$name))" } foreach($AD in $Searchroot){ $Searcher.SearchRoot = "LDAP://$($AD -replace('^(.+)\.(.+)$','DC=$1,DC=$2'))" try { $Searcher.FindAll() # | ForEach-Object {[adsi]$_.path}).Properties Write-LogStep "Collecte ADSI [$AD]",$name ok } catch { Write-LogStep "Collecte ADSI [$name@$AD]",$_ error } } } } end { } } # Export-ModuleMember -Function 'Convert-AdsiUsers','Convert-AdsiFactUsers' Write-LogStep 'Chargement du module ',$PSCommandPath,"$((Get-AllADs).count) Forets" ok |