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.
Partager