Bonjour !
Est-il possible de lister des partages réseaux d'un serveur distant, sans utiliser les classes WMI qui ne fonctionne pas forcement à 100% si le service est HS sur le serveur distant ?
Merci de vos réponses.
Bonjour !
Est-il possible de lister des partages réseaux d'un serveur distant, sans utiliser les classes WMI qui ne fonctionne pas forcement à 100% si le service est HS sur le serveur distant ?
Merci de vos réponses.
Salut,
à moins de trouver un utilitaire fiable pour ce faire, il te faudra utiliser des API Win32 et le Remoting PS.
Je ne connais pas ton environnement, mais si le service WMI est HS il me semble préférable de régler ce problème avant d'essayer de le contourner.
Bon, je sais aussi qu'il y a la théorie et la pratique
Tutoriels Delphi Win32/Delphi .NET/Oracle/PowerShell - FAQ Delphi - FAQ Delphi .NET
Beatus, qui prodest, quibus potest.
réparer WMI n'est pas envisageable car il y a trop de serveurs et cela n'est pas la priorité. Domage aussi que WinRM ne soit pas activé par défaut, ca serait tellement plus simple !
Avec le Remoting PS, c'est toujours l'éternel problème. Il faut l'activer avant. Et sur mon parc de serveur, le service n'est pas activé. Si je voulais l'activé chez mon client, cela prenderai un temps fou pour que cela soit validé (et si c'est validé).
Avec WMI, j'ai quelques serveurs qui présentent cette erreur :
Mon client me demandait d'éviter d'utiliser le WMI pour ces raisons.Get-WmiObject : Access denied
At D:\PowerShell\Script\test.PS1:3 char:2
+ Get-WmiObject -Class "Win32_Share" -NameSpace "root\CIMV2" -ComputerName $ListF ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: ( [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
Sinon, pour NETAPI32, j'ai trouvé cette acticle : https://balladelli.com/netapi-et-powershell/
Cela fonctionne plutôt bien. Je vais voir si je peux faire ce que j'ai besoin avec. Merci pour l'info
Alors avec NETAPI, je peux facilement relever les noms de partage sur des serveurs distants. Cependant, est-il possible de relever les autorisations de partage ? Je ne trouve rien à ce sujet.
On parle bien de permissions de share, et non des permissions du folder NTFS ?
En fait, un Get-Shares avec level 502 a la réponse dans la propriété SecurityDescriptor, enfin...en quelque sorte, car ça se complique un peu. Même beaucoup.
Il y a bien un example sur MSDN mais en C#.
Voici une traduction et adaptation approximative en Powershell:
Il faut tout d'abord revoir le code Netapi et y ajouter quelques fonctions et structures qu'on trouve dans advapi32.dll, ces fonctions vont nous permettre de manipuler SIDs, ACLs et ACEs:
Ensuite on peut faire ceci:
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 [DllImport("advapi32.dll", CharSet = CharSet.Unicode)] public static extern bool GetSecurityDescriptorDacl( IntPtr pSecurityDescriptor, [MarshalAs(UnmanagedType.Bool)] out bool bDaclPresent, ref IntPtr pDacl, [MarshalAs(UnmanagedType.Bool)] out bool bDaclDefaulted ); [DllImport("advapi32.dll", CharSet = CharSet.Unicode)] public static extern bool GetAclInformation( IntPtr pAcl, ref ACL_SIZE_INFORMATION pAclInformation, uint nAclInformationLength, ACL_INFORMATION_CLASS dwAclInformationClass ); [DllImport("advapi32.dll", CharSet = CharSet.Unicode)] public static extern int GetAce( IntPtr aclPtr, int aceIndex, out IntPtr acePtr ); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int GetLengthSid( IntPtr pSID ); [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ConvertSidToStringSid( [MarshalAs(UnmanagedType.LPArray)] byte[] pSID, out IntPtr ptrSid ); [StructLayout(LayoutKind.Sequential)] public struct ACL_SIZE_INFORMATION { public uint AceCount; public uint AclBytesInUse; public uint AclBytesFree; } [StructLayout(LayoutKind.Sequential)] public struct ACE_HEADER { public byte AceType; public byte AceFlags; public short AceSize; } [StructLayout(LayoutKind.Sequential)] public struct ACCESS_ALLOWED_ACE { public ACE_HEADER Header; public int Mask; public int SidStart; } public enum ACL_INFORMATION_CLASS { AclRevisionInformation = 1, AclSizeInformation }
En gros, on récupère l'ACL, qui contient l'ACE et la permission et on s'amuse beaucoup à traduire des offsets de structures et des pointeurs et des buffers vers des objets Powershell, qui sont plus simples à utiliser.
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 . $PSScriptRoot\netapi.ps1 $shares = Get-Shares -level 502 -server localhost foreach ($share in $shares) { $aclPresent = 0 $acl = 0 $aclDefaulted = 0 if ($share.SecurityDescriptor -ne 0) { $ret = [Netapi]::GetSecurityDescriptorDacl($share.SecurityDescriptor,[ref]$aclPresent,[ref]$acl,[ref]$aclDefaulted) if ($aclPresent -eq $true) { $aclInfo = New-Object netapi+ACL_SIZE_INFORMATION $length = [System.Runtime.Interopservices.Marshal]::SizeOf([System.Type]$aclInfo.GetType()) $AclSizeInformation = 2 # Enum defined in ACL_INFORMATION_CLASS $ret = [Netapi]::GetAclInformation($acl,[ref]$aclInfo,$length,$AclSizeInformation) for($i = 0; $i -lt $aclInfo.AceCount; $i++) { $ptr = 0 $aceStruct = New-Object netapi+ACCESS_ALLOWED_ACE $ret = [netapi]::GetAce($acl, $i, [ref]$ptr); $ace = [system.runtime.interopservices.marshal]::PtrToStructure($ptr, [System.Type]$aceStruct.GetType()) if ($null -ne $ace) { $increment = [System.Runtime.Interopservices.Marshal]::OffsetOf([System.Type]$aceStruct.GetType(),"SidStart") $offset = $ptr.ToInt64() $offset += $increment $sidSize = [Netapi]::GetLengthSid($offset) $bytes= $encryptedBytes = New-Object byte[] $sidSize [System.Runtime.Interopservices.Marshal]::Copy($offset, $bytes, 0, $sidSize) $ptrSid = 0 $ret = [Netapi]::ConvertSidToStringSid($bytes, [ref]$ptrSid) $sid = [System.Runtime.Interopservices.Marshal]::PtrToStringAuto($ptrSid) $objSID = New-Object System.Security.Principal.SecurityIdentifier($sid) $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) if (($ace.Mask -band 0x1F01FF) -eq 0x1F01FF) { $right = "Full Control" } elseif (($ace.Mask -band 0x1301BF) -eq 0x1301BF) { $right = "Modify" } elseif (($ace.Mask -band 0x1200A9) -eq 0x1200A9) { $right = "Read" } Write-Output "SID $($objUser.Value) has $right right on share $($share.Name)" } } } } }
j'ai refait un billet qui réunit le tout https://balladelli.com/les-permissions-dun-share/
J'espère que ça peut aider.
Micky
PS. Au fait, merci de m'avoir fait replonger dans ce code, car mon script sur le Netapi avait un bug de taille (free du buffer qui n'a pas lieu d'être), il vaut mieux télécharger la dernière version dans le lien ci-dessus.
Excellent ! Merci d'être passé sur ce post !
Je parle bien des droits du partage et non des droits NTFS.
Effectivement j'avais vu SecurityDescriptor, j'ai cherché des correspondances sur internet, mais rien de fructueux !
Je vais regarder plus en détail ton billet sur ton blog.
Merci encore pour ton script fort utile !
Merci pour ce billet sur votre blog !
Je viens de tester votre script en local avec succès mais sur un serveur distant, j’ai cette erreur :
Exception calling “Translate” with “1” argument(s): “Some or all identity references could not be translated.”
At D:\PowerShell\Script\test.PS1:65 char:7
+ $objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: ( [], MethodInvocationException
+ FullyQualifiedErrorId : IdentityNotMappedException
Je pense qu'il n'arrive pas à faire la conversion, car il doit faire la conversion sur un utilisateur local.
J’avais été obligé de faire ceci sur mon autre script (utilisation de WMI malheureusement) :
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 #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{ Try{ $WmiSid = Get-WmiObject -Class Win32_Group -ComputerName $ComputerName -Filter "DOMAIN='$ComputerName' AND SID='$id'" -ErrorAction SilentlyContinue | Select Caption, SID If(!([string]::IsNullOrEmpty($WmiSid.Caption))){ $name = $WmiSid.Caption }else{ $name = "Le SID de l'utilisateur n'a pas été identifié sur le serveur distant" } }Catch{ $name = "WMI erreur : Le SID de l'utilisateur n'a pas été identifié" } }
Le script complet NETAPI :
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 $Server = "NomDeServeur" #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' } . $PSScriptRoot\netapi.ps1 $shares = Get-Shares -level 502 -server $Server foreach ($share in $shares) { $aclPresent = 0 $acl = 0 $aclDefaulted = 0 if ($share.SecurityDescriptor -ne 0) { $ret = [Netapi]::GetSecurityDescriptorDacl($share.SecurityDescriptor,[ref]$aclPresent,[ref]$acl,[ref]$aclDefaulted) if ($aclPresent -eq $true) { $aclInfo = New-Object netapi+ACL_SIZE_INFORMATION $length = [System.Runtime.Interopservices.Marshal]::SizeOf([System.Type]$aclInfo.GetType()) $AclSizeInformation = 2 # Enum defined in ACL_INFORMATION_CLASS $ret = [Netapi]::GetAclInformation($acl,[ref]$aclInfo,$length,$AclSizeInformation) for($i = 0; $i -lt $aclInfo.AceCount; $i++) { $ptr = 0 $aceStruct = New-Object netapi+ACCESS_ALLOWED_ACE $ret = [netapi]::GetAce($acl, $i, [ref]$ptr); $ace = [system.runtime.interopservices.marshal]::PtrToStructure($ptr, [System.Type]$aceStruct.GetType()) if ($null -ne $ace) { $increment = [System.Runtime.Interopservices.Marshal]::OffsetOf([System.Type]$aceStruct.GetType(),"SidStart") $offset = $ptr.ToInt64() $offset += $increment $sidSize = [Netapi]::GetLengthSid($offset) $bytes= $encryptedBytes = New-Object byte[] $sidSize [System.Runtime.Interopservices.Marshal]::Copy($offset, $bytes, 0, $sidSize) $ptrSid = 0 $ret = [Netapi]::ConvertSidToStringSid($bytes, [ref]$ptrSid) $sid = [System.Runtime.Interopservices.Marshal]::PtrToStringAuto($ptrSid) #Map name to well known sid. If this fails, use .net to get the account if($objUser = $wellKnownSIDs[$sid]){ } else{ #Try to translate the SID to an account Try{ $objSID = New-Object System.Security.Principal.SecurityIdentifier($sid) $objUser = ( $objSID.Translate([System.Security.Principal.NTAccount]) ).Value }Catch{ Try{ $WmiSid = Get-WmiObject -Class Win32_Group -ComputerName $Server -Filter "DOMAIN= '$Server' AND SID='$sid'" -ErrorAction SilentlyContinue | Select Caption, SID If(!([string]::IsNullOrEmpty($WmiSid.Caption))){ $objUser = $WmiSid.Caption }else{ $objUser = $sid #"Le SID de l'utilisateur n'a pas été identifié sur le serveur distant" } }Catch{ $objUser = $sid #"WMI erreur : Le SID de l'utilisateur n'a pas été identifié" } } } if (($ace.Mask -band 0x1F01FF) -eq 0x1F01FF) { $right = "Full Control" } elseif (($ace.Mask -band 0x1301BF) -eq 0x1301BF) { $right = "Modify" } elseif (($ace.Mask -band 0x1200A9) -eq 0x1200A9) { $right = "Read" } Write-Output "$($share.Name), $($objUser) ($right)" } } } } }
Si quelqu'un a une solution pour faire de la conversion de SID local sur un serveur, sans utilisation de WMI, faite moi signe...
Ah cool on en est à $objSID, donc ce n'est plus que de la descente
Oui il s'agit de trouver l'approche la plus fructueuse pour un nom valable/traduit depuis un SID en "S-1....etc", je regarderai ça demain, car de chez moi c'est un peu la mise à jour Win10 qui occupe tous mes PCs .
Au fait, l'exception "Exception calling “Translate” with “1” argument(s): “Some or all identity references could not be translated.” est incroyablement ennuyeuse (j'avais un terme plus correct, mais il n'est pas correct sur un forum public).
En gros cette exception arrive si on n'a pas le droit de traduire une identité. Donc il s'agit de droits Active Directory. Généralement on trouve cette exception, par exemple, quand on exécute une fonction en mode SYSTEM qui a les droits en local, mais aucun droit dans l'AD. Je dis ça car je vois cette exception énormément avec Powershell DSC.
En tout cas on approche du but.
Micky
PS. Désolé j'avais énormément à faire aujourd'hui, et effectivement je n'ai testé le tout qu'en local
Oui effectivement on peut avoir cette exception aussi pour un SID local si on n'a pas les droits de le traduire.
Ce qu'il faudrait dans ce cas, c'est d'utiliser un compte local pour vérifier le SID. Il y a un exemple ici:
https://gallery.technet.microsoft.co...-from-ec384cc1
Mais je ne l'ai pas testé.
Vous pensez que c'est dû à cela ?
Pourtant, j’exécute le script avec un compte administrateur du domaine et donc administrateur local des machines (car le groupe administrateur du domaine fait partir du groupe administrateur local des machine). De ce faite, j'ai les pleins droits sur ces machines distantes.
Je viens de reproduire le problème avec un compte qui est local admin, donc il y a un autre souci.
Ce qui m’embête c'est que l'objet $objSid contient la propriété AccountDomainSid remplie, alors qu'il s'agit d'un compte local, du coup Translate doit s'en servir sans pouvoir aboutir. Les autres permissions qui fonctionnent ont cette propriété vide.
Je pense qu'il faudra traiter ce cas d'une autre façon.
Voici une nouvelle version
Nous allons gérer l'exception et passer par ADSI via WinNT pour récupérer la liste des utilisateurs locaux, et comparer les SIDs
Dans les deux cas, nous avons la variable $name remplie ainsi il faut également modifier le write-output pour l'utiliser:
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 $objSID = New-Object System.Security.Principal.SecurityIdentifier($sid) try { $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) $name = $objUser.Value } catch { $adsi = [adsi]"WinNT://$server" $users = $adsi.Children | where {$_.SchemaClassName -eq 'user'} $name = $users | % { $localSID = New-Object System.Security.Principal.SecurityIdentifier($_.objectSid.Value,0) if ($localSID -eq $sid) { $_.name } } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part Write-Output "$($share.Name), SID $name $right"
Voici le code complet (il faut renseigner $server en début de script)
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 . $PSScriptRoot\netapi.ps1 $server = "" $shares = Get-Shares -level 502 -server $server foreach ($share in $shares) { $aclPresent = 0 $acl = 0 $aclDefaulted = 0 if ($share.SecurityDescriptor -ne 0) { $ret = [Netapi]::GetSecurityDescriptorDacl($share.SecurityDescriptor,[ref]$aclPresent,[ref]$acl,[ref]$aclDefaulted) if ($aclPresent -eq $true) { $aclInfo = New-Object netapi+ACL_SIZE_INFORMATION $length = [System.Runtime.Interopservices.Marshal]::SizeOf([System.Type]$aclInfo.GetType()) $AclSizeInformation = 2 # Enum defined in ACL_INFORMATION_CLASS $ret = [Netapi]::GetAclInformation($acl,[ref]$aclInfo,$length,$AclSizeInformation) for($i = 0; $i -lt $aclInfo.AceCount; $i++) { $ptr = 0 $aceStruct = New-Object netapi+ACCESS_ALLOWED_ACE $ret = [netapi]::GetAce($acl, $i, [ref]$ptr); $ace = [system.runtime.interopservices.marshal]::PtrToStructure($ptr, [System.Type]$aceStruct.GetType()) if ($null -ne $ace) { $increment = [System.Runtime.Interopservices.Marshal]::OffsetOf([System.Type]$aceStruct.GetType(),"SidStart") $offset = $ptr.ToInt64() $offset += $increment $sidSize = [Netapi]::GetLengthSid($offset) $bytes= $encryptedBytes = New-Object byte[] $sidSize [System.Runtime.Interopservices.Marshal]::Copy($offset, $bytes, 0, $sidSize) $ptrSid = 0 $ret = [Netapi]::ConvertSidToStringSid($bytes, [ref]$ptrSid) $sid = [System.Runtime.Interopservices.Marshal]::PtrToStringAuto($ptrSid) $objSID = New-Object System.Security.Principal.SecurityIdentifier($sid) try { $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) $name = $objUser.Value } catch { $adsi = [adsi]"WinNT://$server" $users = $adsi.Children | where {$_.SchemaClassName -eq 'user'} $name = $users | % { $localSID = New-Object System.Security.Principal.SecurityIdentifier($_.objectSid.Value,0) if ($localSID -eq $sid) { $_.name } } } if (($ace.Mask -band 0x1F01FF) -eq 0x1F01FF) { $right = "Full Control" } elseif (($ace.Mask -band 0x1301BF) -eq 0x1301BF) { $right = "Modify" } elseif (($ace.Mask -band 0x1200A9) -eq 0x1200A9) { $right = "Read" } Write-Output "$($share.Name), SID $name $right" } } } } }
Arr, il y a deux mois j'avais fais des recherches avec adsi pour convertir les SID locaux en noms d'utilisateurs. J'avais trouvé des exemples en attaquant le domaine, mais pas une machine. Je vais en profiter pour faire une mise à jour d'un autre script qui utilise cette fonction.
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 $objSID = New-Object System.Security.Principal.SecurityIdentifier($sid) try { $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) $name = $objUser.Value } catch { $adsi = [adsi]"WinNT://$server" $users = $adsi.Children | where {$_.SchemaClassName -eq 'user'} $name = $users | % { $localSID = New-Object System.Security.Principal.SecurityIdentifier($_.objectSid.Value,0) if ($localSID -eq $sid) { $_.name } } }
Et bien un grand merci, ca a répondu à des questions que je me posais il y a longtemps et resté sans réponses...
Correction de la fonction :
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 Function ConvertFrom-SID { [CmdletBinding()] param( [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [string[]]$sid, [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [string[]]$ComputerName ) $objSID = New-Object System.Security.Principal.SecurityIdentifier($sid) try { # Conversion sur le domaine $objUser = $objSID.Translate( [System.Security.Principal.NTAccount]) $name = $objUser.Value } catch { # Conversion sur la machine local $adsi = [adsi]"WinNT://$ComputerName" $users = $adsi.Children | where {($_.SchemaClassName -eq 'user') -OR ($_.SchemaClassName -eq 'group')} $users | ForEach-Object{ $localSID = New-Object System.Security.Principal.SecurityIdentifier($_.objectSid.Value,0) if ($localSID.Value -eq $sid) { $name = $_.Path -Split '/' } } } # Affichage des résultats des Contrôles New-Object -TypeName PSObject -Property @{ SID = $sid Name = $name[$name.count-1] } | Select SID, Name }
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