une belle fonction PS de chez Microsoft pour la conversion des Sid avec gestion d'erreur :
Je vais m'en inspirer.
Code : 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 function ConvertFrom-SID { <# .SYNOPSIS Convert SID to user or computer account name .DESCRIPTION Convert SID to user or computer account name .PARAMETER SID One or more SIDs to convert .EXAMPLE ConvertFrom-SID S-1-5-21-2139171146-395215898-1246945465-2359 .EXAMPLE 'S-1-5-32-580' | ConverFrom-SID .FUNCTIONALITY Active Directory .NOTES SID conversion for well known SIDs from http://support.microsoft.com/kb/243330 #> [CmdletBinding()] param( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [string[]]$sid ) Begin{ #well known SID to name map $wellKnownSIDs = @{ 'S-1-0' = 'Null Authority' 'S-1-0-0' = 'Nobody' 'S-1-1' = 'World Authority' 'S-1-1-0' = 'Everyone' 'S-1-2' = 'Local Authority' 'S-1-2-0' = 'Local' 'S-1-2-1' = 'Console Logon' 'S-1-3' = 'Creator Authority' 'S-1-3-0' = 'Creator Owner' 'S-1-3-1' = 'Creator Group' 'S-1-3-2' = 'Creator Owner Server' 'S-1-3-3' = 'Creator Group Server' 'S-1-3-4' = 'Owner Rights' 'S-1-5-80-0' = 'All Services' 'S-1-4' = 'Non-unique Authority' 'S-1-5' = 'NT Authority' 'S-1-5-1' = 'Dialup' 'S-1-5-2' = 'Network' 'S-1-5-3' = 'Batch' 'S-1-5-4' = 'Interactive' 'S-1-5-6' = 'Service' 'S-1-5-7' = 'Anonymous' 'S-1-5-8' = 'Proxy' 'S-1-5-9' = 'Enterprise Domain Controllers' 'S-1-5-10' = 'Principal Self' 'S-1-5-11' = 'Authenticated Users' 'S-1-5-12' = 'Restricted Code' 'S-1-5-13' = 'Terminal Server Users' 'S-1-5-14' = 'Remote Interactive Logon' 'S-1-5-15' = 'This Organization' 'S-1-5-17' = 'This Organization' 'S-1-5-18' = 'Local System' 'S-1-5-19' = 'NT Authority' 'S-1-5-20' = 'NT Authority' 'S-1-5-32-544' = 'Administrators' 'S-1-5-32-545' = 'Users' 'S-1-5-32-546' = 'Guests' 'S-1-5-32-547' = 'Power Users' 'S-1-5-32-548' = 'Account Operators' 'S-1-5-32-549' = 'Server Operators' 'S-1-5-32-550' = 'Print Operators' 'S-1-5-32-551' = 'Backup Operators' 'S-1-5-32-552' = 'Replicators' 'S-1-5-64-10' = 'NTLM Authentication' 'S-1-5-64-14' = 'SChannel Authentication' 'S-1-5-64-21' = 'Digest Authority' 'S-1-5-80' = 'NT Service' 'S-1-5-83-0' = 'NT VIRTUAL MACHINE\Virtual Machines' 'S-1-16-0' = 'Untrusted Mandatory Level' 'S-1-16-4096' = 'Low Mandatory Level' 'S-1-16-8192' = 'Medium Mandatory Level' 'S-1-16-8448' = 'Medium Plus Mandatory Level' 'S-1-16-12288' = 'High Mandatory Level' 'S-1-16-16384' = 'System Mandatory Level' 'S-1-16-20480' = 'Protected Process Mandatory Level' 'S-1-16-28672' = 'Secure Process Mandatory Level' 'S-1-5-32-554' = 'BUILTIN\Pre-Windows 2000 Compatible Access' 'S-1-5-32-555' = 'BUILTIN\Remote Desktop Users' 'S-1-5-32-556' = 'BUILTIN\Network Configuration Operators' 'S-1-5-32-557' = 'BUILTIN\Incoming Forest Trust Builders' 'S-1-5-32-558' = 'BUILTIN\Performance Monitor Users' 'S-1-5-32-559' = 'BUILTIN\Performance Log Users' 'S-1-5-32-560' = 'BUILTIN\Windows Authorization Access Group' 'S-1-5-32-561' = 'BUILTIN\Terminal Server License Servers' 'S-1-5-32-562' = 'BUILTIN\Distributed COM Users' 'S-1-5-32-569' = 'BUILTIN\Cryptographic Operators' 'S-1-5-32-573' = 'BUILTIN\Event Log Readers' 'S-1-5-32-574' = 'BUILTIN\Certificate Service DCOM Access' 'S-1-5-32-575' = 'BUILTIN\RDS Remote Access Servers' 'S-1-5-32-576' = 'BUILTIN\RDS Endpoint Servers' 'S-1-5-32-577' = 'BUILTIN\RDS Management Servers' 'S-1-5-32-578' = 'BUILTIN\Hyper-V Administrators' 'S-1-5-32-579' = 'BUILTIN\Access Control Assistance Operators' 'S-1-5-32-580' = 'BUILTIN\Remote Management Users' } } Process { #loop through provided SIDs foreach($id in $sid){ #Map name to well known sid. If this fails, use .net to get the account if($name = $wellKnownSIDs[$id]){ } else{ #Try to translate the SID to an account Try{ $objSID = New-Object System.Security.Principal.SecurityIdentifier($id) $name = ( $objSID.Translate([System.Security.Principal.NTAccount]) ).Value } Catch{ $name = "Not a valid SID or could not be identified" Write-Verbose "$id is not a valid SID or could not be identified" } } #Display the results New-Object -TypeName PSObject -Property @{ SID = $id Name = $name } | Select SID, Name } } }
Un traitement d'arborescence qui n'est plus récursif, mais itératif basé sur une pile :
La prochaine étape : gérer le flux du pipeline par bloc.
Code : 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 Add-type -Path C:\Users\Laurent\Downloads\AlphaFS-1.5-BinAndDocs\Debug\AlphaFS.dll function Get-FilesOrDirectories{ <# .SYNOPSIS Gets the files or directories with long paths, that is, paths that exceed 259 characters. #> Param ( #Specifies a path to one location. [ValidateNotNullOrEmpty()] #todo notnull uniquement cf. api [string] $path, #The search pattern. A combinaison of '*' or '?'. [ValidateNotNullOrEmpty()] [string] $searchPattern, #Specifies whether to search the current directory, or the current directory and all subdirectories. #AllDirectories : Includes the current directory and all its subdirectories in a search operation. This option includes reparse points such as mounted drives and symbolic links in the search. #TopDirectoryOnly : Includes only the current directory in a search operation. [System.IO.SearchOption] $searchOption=[System.IO.SearchOption]::AllDirectories, #if set return only the directories, if not, return only the files. [switch] $directories ) $dirs = new-object System.Collections.Generic.Stack[string] $path=[Alphaleonis.Win32.Filesystem.Path]::GetLongPath($path) if ($path.EndsWith([System.IO.Path]::DirectorySeparatorChar, [System.StringComparison]::Ordinal) -and $path.EndsWith([System.IO.Path]::AltDirectorySeparatorChar, [System.StringComparison]::Ordinal)) { $dirs.Push($path) } else { $dirs.Push($path + [System.IO.Path]::DirectorySeparatorChar) } while ($dirs.Count -gt 0) { $tmpDir = $dirs.Pop() if ($searchOption -eq 'AllDirectories') { Write-debug '$searchOption -eq AllDirectories' try { $dirEnumerator = new-object Alphaleonis.Win32.Filesystem.FileSystemEntryEnumerator($null, ($tmpDir + "*"),$true) while ($dirEnumerator.MoveNext()) { if ($dirEnumerator.Current.IsDirectory) { Write-debug "dir $($tmpDir + $dirEnumerator.Current.FileName + [System.IO.Path]::DirectorySeparatorChar)" $dirs.Push(($tmpDir + $dirEnumerator.Current.FileName + [System.IO.Path]::DirectorySeparatorChar)) } } } finally { #On référence l'objet itérateur et pas l'itération de l'objet %-) if ($dirEnumerator.PsBase -ne $null) { $dirEnumerator.Dispose() } } } if ($directories) { Write-debug 'If directories' try { $enumerator = new-object Alphaleonis.Win32.Filesystem.FileSystemEntryEnumerator($null, ($tmpDir + $searchPattern),$true) while ($enumerator.MoveNext()) { if ($enumerator.Current.IsDirectory) { Write-debug "file $($tmpDir + $enumerator.Current.FileName)" Write-Output ($tmpDir + $enumerator.Current.FileName) } } } finally { if ($enumerator.PsBase -ne $null) { $enumerator.Dispose() } } } else { Write-debug "not directories" try { $enumerator = new-object Alphaleonis.Win32.Filesystem.FileSystemEntryEnumerator($null, ($tmpDir + $searchPattern),$false) while ($enumerator.MoveNext()) { if ($enumerator.Current.IsFile) { Write-debug "file $($tmpDir + $enumerator.Current.FileName)" Write-Output ($tmpDir + $enumerator.Current.FileName) } } } finally { if ($enumerator.PsBase -ne $null) { $enumerator.Dispose() } } } } }#Get-FilesOrDirectories Get-FilesOrDirectories -path c:\temp\001 -searchPattern '*' -searchOption AllDirectories
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
Un exemple :
Code : 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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 function Out-SplittingCSV { <# .SYNOPSIS Ecrit dans un fichier des objets au format CSV. Cette fonction peut générer plusieurs fichiers regroupant un nombre limité d'objets. #> [CmdletBinding()] Param( #Objet à convertir. [ValidateNotNull()] [Parameter(Mandatory=$True,ValueFromPipeline=$True)] $InputObject, #Nom de base du fichier. #Chaque nom de fichier est incrémenté à partir de zéro. #Si le fichier existe il est écrasé. [ValidateNotNullOrEmpty()] [Parameter(Position=0,Mandatory=$True)] $Path, #Nombre d'objet maximum à écrire dans un fichier. #Voir le paramètre -Validation [Parameter(Position=1,Mandatory=$True,ParameterSetName="Count")] [ValidateScript({$_ -ge 1})] [int]$Count, #Noms des propriétés d'un objet à convertir. #Peut être une hashtable normalisé, consulter la documentation du paramètre -Property du cmdlet Select-Object. [ValidateNotNullOrEmpty()] [Parameter(Position=2)] [Object[]]$Property='*', #Code de validation des clés permettant de 'regrouper' les objets reçu du pipeline. #Son usage retarde la création d'un nouveau fichier tant que le code de validation renvoi $true alors que la valeur maximum de Count est atteinte ou dépassée. #On évite ainsi de disperser des informations dont la clé est identique. [ValidateNotNullOrEmpty()] [Parameter(Position=3)] [ScriptBlock] $Validation, #Spécifie un délimiteur pour séparer les valeurs de propriété. #Par défaut contient la valeur de la clé de registre suivante : # hkcu:\Control Panel\International\sList #Si cette clé n'existe pas la valeur par défaut sera la virgule ',' [ValidateNotNullOrEmpty()] [Parameter(Position=4)] [char] $Delimiter, #Spécifie le type d'encodage pour le fichier cible. #Les valeurs valides sont ASCII, UTF8, UTF7, UTF32, Unicode, BigEndianUnicode, Default et OEM. #La valeur par défaut est UTF8. [Parameter(Position=5)] [Text.Encoding]$Encoding = [Text.Encoding]::UTF8, #Omet l'en-tête d'informations de type de la sortie. #Par défaut, la chaîne de la sortie contient « #TYPE », suivi du nom complet du type de l'objet .NET Framework. #Le type inséré par ConvertTo-Csv correspond au premier objet reçu dans le pipeline. #Si les objets reçus ne sont pas du même type, le typename affiché par Get-Member peut ne pas correspondre. [switch] $NoTypeInformation ) Begin { $isValidateKey=$PSBoundParameters.ContainsKey('Validation') if (!$isValidateKey) { $Validation= {$true} } [Switch] $isVerbose= $null [void]$PSBoundParameters.TryGetValue('Verbose',[REF]$isVerbose) if ($isVerbose) { $VerbosePreference='Continue' } $_EA= $null [void]$PSBoundParameters.TryGetValue('ErrorAction',[REF]$_EA) if ($_EA -eq $null) #todo { #Récupère la valeur du contexte de l'appelant $ErrorActionPreference=$PSCmdlet.SessionState.PSVariable.Get('ErrorActionPreference').Value } else { #Priorité: On remplace sa valeur $ErrorActionPreference=$_EA } if (!$PSBoundParameters.ContainsKey('Delimiter')) { try { $Delimiter=(Get-ItemProperty 'hkcu:\Control Panel\International' sList -ea Stop).sList } catch { #inexistent key or null value $Delimiter=',' Write-Warning "Use delimiter '$Demlimiter'." } } function OpenStream { Write-debug "Increment=$Increment" #<%REMOVE%> $FileName='{0}\{1}{2}{3}' -F $FileInfo.Directory,$FileInfo.BaseName,((Get-Variable Increment -scope 1).Value++),$FileInfo.Extension Write-Debug "OpenStream $FileName" #<%REMOVE%> try { $Writer=New-Object IO.StreamWriter $FileName, $false, $Encoding } catch { $Er= New-Object System.Management.Automation.ErrorRecord( $_.Exception, "IOError", "OpenError", $FileName ) #Stop the pipeline now ! $PSCmdlet.ThrowTerminatingError($Er) } try { if ($TYPEInformation -ne [string]::Empty) { $Writer.WriteLine($TYPEInformation) } if ($HeaderInformation -ne [string]::Empty) { $Writer.WriteLine($HeaderInformation) } } catch { $Er= New-Object System.Management.Automation.ErrorRecord( $_.Exception, "IOError", "WriteError", $FileName ) $PSCmdlet.ThrowTerminatingError($Er) } Write-Output $Writer }#OpenStream function CloseStream { if ($Writer -ne $null) { Write-Verbose "Out-SplittingCSV : $($Writer.BaseStream.Name)" try { $Writer.Close() } catch { $Er= New-Object System.Management.Automation.ErrorRecord( $_.Exception, "IOError", "CloseError", $FileName ) $PSCmdlet.ThrowTerminatingError($Er) } } }#CloseStream $TYPEInformation=$HeaderInformation=[string]::Empty $Increment=$Number=0 $PreviousObject=$null $isAssignHeader=$true $Writer = $Null $FileInfo=New-object System.IO.FileInfo $Path } Process { Write-Debug "${Number}/$Count" #<%REMOVE%> if ($isAssignHeader) { $Csv=$InputObject|Select-Object -Property $Property|ConvertTo-Csv -Delimiter $Delimiter -NoTypeInformation:$NoTypeInformation if ($NoTypeInformation) { $HeaderInformation =$Csv[0] Write-Debug "HeaderInformation= $InputObject" #<%REMOVE%> } else { $TYPEInformation=$Csv[0] Write-Debug "TYPEInformation= $InputObject" #<%REMOVE%> $HeaderInformation =$Csv[1] Write-Debug "HeaderInformation= $InputObject" #<%REMOVE%> } $isAssignHeader=$false $PreviousObject=$InputObject $Writer = OpenStream } Write-debug "$($Number -ge $Count) $(&$Validation -Current $InputObject -Previous $PreviousObject)" #<%REMOVE%> if (($Number -ge $Count) -and (&$Validation -Current $InputObject -Previous $PreviousObject)) { Write-Debug "Split CSV file" #<%REMOVE%> CloseStream $Writer = OpenStream $Number=0 } if ($isValidateKey) { $PreviousObject=$InputObject } try { $Writer.WriteLine((($InputObject|Select-Object -Property $Property|ConvertTo-Csv -Delimiter $Delimiter -NoTypeInformation)[1]) ) } catch { $Er= New-Object System.Management.Automation.ErrorRecord( $_.Exception, "IOError", "WriteError", $Writer.BaseStream.Name ) $PSCmdlet.ThrowTerminatingError($Er) } $Number++ } End { #Close Current stream CloseStream } } #Out-SplittingCSV
Cela reste à tester...
Code : 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 del 'C:\temp\LgPath*.csv' -whatif #On crée des fichiers regroupant 10 objets max dir $pshome -rec|Out-SplittingCSV -Path 'c:\temp\LgPath' -Count 10 -Property PSPath,Name,Size -Verbose $KeyValidation={ param ($Current, $Previous) $Key='PSParentPath' Write-debug "Input : $($Current.$Key)" #<%REMOVE%> Write-debug "Last : $($Previous.$Key)" #<%REMOVE%> $Current.$Key -ne $Previous.$Key } del 'C:\temp\LgPath*.csv' -whatif #On crée des fichiers regroupant 10 objets ou plus tant que la propriété 'PSParentPath' #de l'objet courant(reçu du pipeline) est identique à celle de l'objet traité précédement. dir $pshome -rec|Out-SplittingCSV -Path 'c:\temp\LgPath' -Count 10 -Validation $KeyValidation -Property PSPath,Name,Size -Verbose
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
Salut Laurent,
Merci pour ton aide. je vais testé cela.
Sinon, j'ai testé le script (de vendredi dernier) et j'ai pu recevoir mes 1er audits avec succès !
Encore mille mercis
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
Alors sur le plus gros des partages, j'ai remonté 4,5 millions d'objets avec un temps d'exécution de 8H et un fichier CSV de 1,1Go (que j'ai découpé avec un autre logiciel )
Ensuite, en convertissant les CVS en XLSX, je suis arrivé à un fichier de 426ko !!!
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
J'ai mes fichiers CSV générés par le script, que je découpe en fichiers CSV de 500 000 lignes afin de pouvoir lès ouvrir via Excel. Ensuite, j'enregistre les CSV en XLSX depuis Excel. Puis, je fusionne mes fichiers Excel en un seul fichier XLSX. J'arrive à un fichier de quelques Ko. J'ai fais cela manuellement, cela ne prend pas beaucoup de temps (à peine 5 min).
Bonjour Laurent,
Je réutilise le script que l'on avait réalisé en octobre dernier et j'ai un problème avec
Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part $dirACL = $dir.GetAccessControl("Access")
Lorsque je fais le test avec un jeu en local, pas d'erreur. Avec un jeu sur un lecteur réseau, j'ai ce problème. En octobre dernier, je n'avais pas ce problème.Exception calling "GetAccessControl" with "1" argument(s): "Destination array is not long enough to copy all the required data. Check array length and
offset.
Je viens de faire des tests cet après midi avec la méthode GetAccessControl, mais j'ai du mal à comprendre comment elle fonctionne.
J'ai essayé de faire quelques chose avec ce bout de code :
Code powershell : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 Add-type -Path D:\PowerShell\Script\AlphaFS.2.0.1\lib\net451\AlphaFS.dll $FilePath = [Alphaleonis.Win32.Filesystem.Path]::GetLongPath("\\SRV001\i$\Fichier\Commun_01") $FSObject = New-Object Alphaleonis.Win32.Filesystem.DirectoryInfo($FilePath) $ItemACL = $FSObject.GetAccessControl($FilePath,[System.Security.AccessControl.AccessControlSections]::Access, [Alphaleonis.Win32.Filesystem.PathFormat]::LongFullPath) $ItemExplicitACEs = $ItemACL.GetAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier])
et ça plante toujours au niveau des arguments de GetAccessControl.
Que faire ?
Déjà récupérer le détail de l'erreur.
Si c'est la dernière version de la librairie, le mieux est de s'adresser aux développeurs.
La volumétrie n'a pas changée ?
Le pb survient dés l'appel ou après un certain temps de traitement ?
Peut être essayé de transformer le code récursif en itératif...
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
En faite, j'ai testé avec la librairie 1.5 (celle utilisé en Octobre) et j'ai cette erreur.
La volumétrie est moindre (5TO). Je suis chez un autre client.
J'ai voulu faire un test avec la nouvelle pour voir si cela corrigeait le problème.
Le problème survient dès l'appel.
As-tu le même pb si tu recherches un seul chemin, par exemple à la racine ?
Il faudrait le détail de l'exception via $StackTrace.
En recherchant dans le code :
Fichier : ..\AlphaFS-develop\AlphaFS-develop\AlphaFS\Filesystem\File Class\File.GetAccessControl.cs
Classe : internal static T GetAccessControlCore<T>
On tombe sur ceci :
Le mieux est d'ouvrir un bug sur le site du projet.
Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 uint length = Security.NativeMethods.GetSecurityDescriptorLength(pSecurityDescriptor); // Seems not to work: Method .CopyTo: length > Capacity, so an Exception is thrown. //byte[] managedBuffer = new byte[length]; //pSecurityDescriptor.CopyTo(managedBuffer, 0, (int) length); byte[] managedBuffer = pSecurityDescriptor.ToByteArray(0, (int)length);
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
voici l'erreur complète :
Si j'analyse qu'un seul dossier, même problème.Exception calling "GetAccessControl" with "1" argument(s): "Destination array is not long enough to copy all the required data. Check array length and
offset.
Parameter name: binaryForm"
At D:\test\Audit_NTFS_GROUP.PS1:148 char:2
+ $dirACL = $dir.GetAccessControl("Access")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : ArgumentOutOfRangeException
You cannot call a method on a null-valued expression.
At D:\test\Audit_NTFS_GROUP.PS1:149 char:2
+ $accessRules = $dirACL.GetAccessRules($true, $true, [System.Security.Principal. ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
La différence que j'ai par rapport à Octobre 2014, c'est que j’exécute le script sur un Windows 2012, alors qu'en octobre j'étais sur un Windows 2003.
Sur le Windows 2012, lorsque je fais une analyse en local, aucun problème, sur le réseau (UNC ou mappé) problème. Étonnant !
Je vais aller voir sur le forum du développeur de la DLL.
Merci encore de ton aide. ;)
Il faudrait utiliser Resolve-Error dispo sur le net ou $stracktrace à partir de PS v3.
Ainsi on peut peut être retrouver l'origine de l'exception
Que donne l'appel en lui passant ce chemin :
Si tu t'adresses aux développeurs fournit leur un cas reproductible.
Code : Sélectionner tout - Visualiser dans une fenêtre à part \\localhost\c$
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
Bon, fausse alerte, cela fonctionne bien sur Windows 2012 R2.
J'avais oublié de faire une élévation de droits sur la console PowerShell. Je pensais l'avoir fait alors que non.
Je viens de rencontrer une limitation de la librairie AlphaFS par rapport à mon script. En effet, il m'est impossible de résoudre les SID des groupes/utilisateurs locaux enregistré sur un autre serveur.
Cette limitation est aussi présente avec Get-ACL.
Un exemple sous Windows d'un répertoire sur le réseau où que les groupes local sont configuré. Windows résout correctement les nom des groupes.
La même chose via PowerShell depuis AlphaFS et Get-ACL
On ne peut résoudre les SID que de domaines ou du serveur local sur lequel est exécuté les commandes.
C'est un peu problématique cette limitation. Reste à essayer de résoudre les SID locaux des serveur distant, chose que j'ai essayé de faire via des requêtes WMI, mais le temps de réponse est très long.
WQL devrait réduire la latence (faiblement mais quand même ...)
https://msdn.microsoft.com/en-us/lib...=vs.85%29.aspx
Le gourou dicte la ligne (de commande) à suivre ...
Penser à lire le Tutoriel Batch ou a consulter la FAQ Batch et ses contributions,
ainsi que le Cour sur la ligne de commande et des scripts
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager