Bonjour à tous,
Je suis nouveau dans une boite d'informatique, et je souhaite mettre en place un script PowerShell permettant l'export et l'import de manière paramètrables pour des utilisateurs Active Directory.
Pour l'instant, j'ai le script suivant, qui coince sur l'import maintenant. Le message qu'il me renseigne est que les paramètres passés dans les attributs n'existe pas :
Voici le script dans sa dernière version :
Code POWERSHELL : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 ################################## ## Export - Import AD Users ## ## Creator : RTH ## ## Date : 02-01-2020 ## ## Last update : 08-01-2020 ## ################################## ####### ## ask the user the action he want's to operate ####### $csvFileName = "ad-export.csv" $delimiter = ';' do{ Write-host "Welcome in AD Users Export / Import" Write-Host "What action do you wanna operate ?" Write-host "Export active Users using the selected fields : (1)" Write-Host "Import a list of Users based on a csv file : (2)" $action = Read-Host -Prompt "Your choice" }while ( !($action -eq "1") -and !($action -eq "2")) # Import active directory module for running AD cmdlets Import-Module activedirectory if( $action -eq "1"){ $chosenParameters = New-Object System.Collections.Generic.List[string] ## READ THE PARAMETER FILE for the export ## $parameterFile = "export-parameters.txt" if (!(Test-Path -Path (join-path $PSScriptRoot $parameterFile))){ if(!(Test-Path -Path (join-path $PSScriptRoot "export-parameters-default.txt"))){ Write-Host "Error file not found" -ForegroundColor Red Exit } Write-Host "Only Default file found !" -ForegroundColor Yellow $parameterFile = join-path $PSScriptRoot "export-parameters-default.txt" } ## Get elements in file ForEach($Parameter in (Get-Content -Path $parameterFile)){ if( $Parameter.StartsWith("#") ){ $chosenParameters.Add($Parameter.subString(1)) } } ## List elements $param = "" foreach( $option in $chosenParameters){ $param += $option+", " } if( $param.EndsWith(', ')){ $param = $param.Substring(0, ($param.Length-2)) } Write-Host "Param = $param" Get-ADUser -filter 'Enabled -eq $true' -property (foreach{$chosenParameters}) | Select-Object (foreach{$chosenParameters}) | Export-Csv -Path (Join-Path $PSScriptRoot $csvFileName) -Delimiter $delimiter -NoTypeInformation } elseif ($action -eq "2"){ $chosenParameters = New-Object System.Collections.Generic.List[string] $generatedDN = $null $userFailed = New-Object System.Collections.ArrayList $userSuccess = New-Object System.Collections.ArrayList $userExist = New-Object System.Collections.ArrayList ## READ THE PARAMETER FILE for the import ## $parameterFile = "export-parameters.txt" if (!(Test-Path -Path (join-path $PSScriptRoot $parameterFile))){ if(!(Test-Path -Path (join-path $PSScriptRoot "export-parameters-default.txt"))){ Write-Host "Error file not found" -ForegroundColor Red Exit } Write-Host "Only Default file found !" -ForegroundColor Yellow $parameterFile = join-path $PSScriptRoot "export-parameters-default.txt" } ## Get the selected elements from file ForEach($Parameter in (Get-Content -Path $parameterFile)){ if( $Parameter.StartsWith("#") ){ $chosenParameters.Add($Parameter.subString(1)) } } $parameterTable = @{} for($i = 0 ; $i -lt $chosenParameters.Count ; $i++ ){ $parameterTable.Add($chosenParameters[$i], $null) } #Store the data from ADUsers.csv in the $ADUsers variable $ADUsers = Import-csv (Join-Path $PSScriptRoot $csvFileName) -Delimiter $delimiter #Loop through each row containing user details in the CSV file foreach ($User in $ADUsers) { $exist = $null ## Verify if the OU of the current User Exists #Write-Host "ParameterTable "$parameterTable.Contains("DistinguishedName") if( !$parameterTable.Contains("DistinguishedName")){ Write-Host "OU Generation unavailable because the DistinguishedName field doesn't exist." -ForegroundColor Red Write-Host "Import aborted due to missing field." -ForegroundColor Red exit } $distinguishedName = $user.DistinguishedName if( !($distinguishedName -eq $null)){ $splittedDN = $distinguishedName.Split(",") $splittedDN = $splittedDN[1..($splittedDN.Count)] $rebuildDN = $splittedDN -join "," } else{ Write-Host "DistinguishedName value is NULL" -ForegroundColor Red } Write-Host "This is the generated DistinguishedName that's going to be used : "$rebuildDN $generatedDN = $rebuildDN try{ $generatedDNExist = [adsi]::Exists("LDAP://$generatedDN") } catch{ Write-Host "The specified Path for the path doesn't exist." -ForegroundColor Red Write-Host "The User [$User.DisplayName] is going to be created in the Default Users Group of the Domain" $generatedDN = Get-ADDomain | select UsersContainer } ## create the table containing all the infos from the User var ## Convert the User to HashTable $HashUser = @{} $User.PSObject.Properties | ForEach-Object{ if( $_.value -ne $null -and $_.value -ne "" ){ $name = "'"+$_.name+"'" $value = '"'+$_.value+'"' $HashUser.Add($name, $value) } } #Check to see if the user already exists in AD write-host "HashTable :" ($HashUser |Out-String) $username = $HashUser["'SamAccountName'"] #$exist = Get-ADUser -Identity $username -Properties * $exist = [bool](Get-ADUser -Filter { SamAccountName -eq $username }) #if (Get-ADUser -Identity $username -Properties *) { #If user does exist, give a warning if( $exist ){ Write-Host "A user account with username $username already exist in Active Directory." -ForegroundColor Red $userExist.Add($username) } else { #User does not exist then proceed to create the new user account try{ $HashUser.Remove("'SamAccountName'") New-ADUser -Name $HashUser["'name'"] -OtherAttributes $HashUser $userSuccess.Add($HashUser["'name'"]) } catch{ Write-Host $_.Exception.Message $userFailed.Add($HashUser["'name'"]) } } } Write-Host "Report of the export action" Write-Host "Successfully added Users " -ForegroundColor Green Write-Host $userSuccess Write-Host "Already existing Users" -ForegroundColor Yellow Write-Host $userExist Write-Host "Error on adding Users" -ForegroundColor Red Write-Host $userFailed }
Je l'accorde, c'est encore un peu le bazard car je suis encore en phase de test du script en question. Une fois qu'il sera opérationnel, je "rangerai" un peu dedans et mettrai les commentaires où il se doit (et ferai une petite doc correspondante).
Voici les sorties console que j'ai lors du lancement du script :
Code CONSOLE : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 PS C:\Users\Administrator> C:\Users\Administrator\Desktop\bulk_users1.ps1 Welcome in AD Users Export / Import What action do you wanna operate ? Export active Users using the selected fields : (1) Import a list of Users based on a csv file : (2) Your choice: 2 Only Default file found ! This is the generated DistinguishedName that's going to be used : CN=Users,DC=test,DC=domain,DC=com HashTable : Name Value ---- ----- 'DistinguishedName' "CN=Administrator,CN=Users,DC=test,DC=domain,DC=com" 'Enabled' "True" 'Name' "Administrator" 'CN' "Administrator" 'CannotChangePassword' "False" 'SamAccountName' "Administrator" Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:214' [DBG]: PS C:\Users\Administrator>> Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:220' [DBG]: PS C:\Users\Administrator>> The specified directory service attribute or value does not exist Parameter name: 'CannotChangePassword' Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:233' [DBG]: PS C:\Users\Administrator>> 0 This is the generated DistinguishedName that's going to be used : CN=Users,DC=test,DC=domain,DC=com HashTable : Name Value ---- ----- 'Name' "R T - test" 'GivenName' "R" 'Enabled' "True" 'DistinguishedName' "CN=R T - test,CN=Users,DC=test,DC=domain,DC=com" 'DisplayName' "R T - test" 'CannotChangePassword' "False" 'CN' "R T - test" 'SamAccountName' "rt-test" 'Surname' "T" Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:214' [DBG]: PS C:\Users\Administrator>> Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:220' [DBG]: PS C:\Users\Administrator>> The specified directory service attribute or value does not exist Parameter name: 'CannotChangePassword' Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:233' [DBG]: PS C:\Users\Administrator>> 1 This is the generated DistinguishedName that's going to be used : CN=Users,DC=test,DC=domain,DC=com HashTable : Name Value ---- ----- 'Name' "R T2 - test" 'GivenName' "R" 'Enabled' "True" 'DistinguishedName' "CN=R T2 - test,CN=Users,DC=test,DC=domain,DC=com" 'DisplayName' "R T2 - test" 'CannotChangePassword' "False" 'CN' "R T2 - test" 'SamAccountName' "rt2-test" 'Surname' "T" Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:214' [DBG]: PS C:\Users\Administrator>> Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:220' [DBG]: PS C:\Users\Administrator>> The specified directory service attribute or value does not exist Parameter name: 'CannotChangePassword' Hit Line breakpoint on 'C:\Users\Administrator\Desktop\bulk_users1.ps1:233' [DBG]: PS C:\Users\Administrator>> 2 Report of the export action Successfully added Users Already existing Users Error on adding Users "Administrator" "R T - test" "R T2 - test" PS C:\Users\Administrator>
Pourriez-vous me dire pourquoi il rouspette sur les attributs que je lui renseigne ? J'ai trouver sur la toile, plusieurs script, mais à chaque fois, il code les paramètres en dur dans la commande New-ADUser, ce que personnellement, je trouve complètement bête, car on perd toute généricité du code.
[EDIT] je viens de trouver une information à priori importante dans le Get-Help New-ADUser qui dit ceci :
DESCRIPTION
The New-ADUser cmdlet creates a new Active Directory user. You can set commonly used user property values by using the cmdlet parameters.
Property values that are not associated with cmdlet parameters can be set by using the OtherAttributes parameter. When using this parameter be sure to place
single quotes around the attribute name as in the following example.
Donc, j'ai la liste des paramètres suivantes :
et j'y retrouve bien, en paramètres, le CannotChangePassword, ce qui explique donc pourquoi je ne pourrais pas le passer par OtherAttributes, ou me trompe-je ??
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 [-Name] <String> [-AccountExpirationDate <DateTime>] [-AccountNotDelegated <Boolean>] [-AccountPassword <SecureString>] [-AllowReversiblePasswordEncryption <Boolean>] [-AuthenticationPolicy <ADAuthenticationPolicy>] [-AuthenticationPolicySilo <ADAuthenticationPolicySilo>] [-AuthType {Negotiate | Basic}] [-CannotChangePassword <Boolean>] [-Certificates <X509Certificate[]>] [-ChangePasswordAtLogon <Boolean>] [-City <String>] [-Company <String>] [-CompoundIdentitySupported <Boolean>] [-Country <String>] [-Credential <PSCredential>] [-Department <String>] [-Description <String>] [-DisplayName <String>] [-Division <String>] [-EmailAddress <String>] [-EmployeeID <String>] [-EmployeeNumber <String>] [-Enabled <Boolean>] [-Fax <String>] [-GivenName <String>] [-HomeDirectory <String>] [-HomeDrive <String>] [-HomePage <String>] [-HomePhone <String>] [-Initials <String>] [-Instance <ADUser>] [-KerberosEncryptionType {None | DES | RC4 | AES128 | AES256}] [-LogonWorkstations <String>] [-Manager <ADUser>] [-MobilePhone <String>] [-Office <String>] [-OfficePhone <String>] [-Organization <String>] [-OtherAttributes <Hashtable>] [-OtherName <String>] [-PassThru] [-PasswordNeverExpires <Boolean>] [-PasswordNotRequired <Boolean>] [-Path <String>] [-POBox <String>] [-PostalCode <String>] [-PrincipalsAllowedToDelegateToAccount <ADPrincipal[]>] [-ProfilePath <String>] [-SamAccountName <String>] [-ScriptPath <String>] [-Server <String>] [-ServicePrincipalNames <String[]>] [-SmartcardLogonRequired <Boolean>] [-State <String>] [-StreetAddress <String>] [-Surname <String>] [-Title <String>] [-TrustedForDelegation <Boolean>] [-Type <String>] [-UserPrincipalName <String>] [-Confirm] [-WhatIf] [<CommonParameters>]
Mais maintenant, comment générer une commande New-ADUser de manière à disposer de paramètres générique en fonction des paramètres que l'utilisateur aura définit dans le fichier CSV / txt de sélection des paramètres pour l'export ?
La liste des paramètres sélectionnable est basée sur le document txt suivant : export-parameters-default.txt
Et comment être certain, en générant la commande, que le paramètre renseigné est un paramètre valide ?
En vous remerciant pour les quelques pistes et informations qu'il vous sera possible de m'apporter à la compréhension de la situation, je vous souhaite à tous une superbe journée.
Raph
Partager