IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Scripts/Batch Discussion :

Lister les partages réseau sans WMI, possible ? [PowerShell]


Sujet :

Scripts/Batch

  1. #1
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut Lister les partages réseau sans WMI, possible ?
    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.

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    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

  3. #3
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    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 !

  4. #4
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    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 :

    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
    Mon client me demandait d'éviter d'utiliser le WMI pour ces raisons.

    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

  5. #5
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    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.

  6. #6
    Membre habitué
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2015
    Messages : 66
    Points : 126
    Points
    126
    Par défaut
    Citation Envoyé par arnaudperfect Voir le message
    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:

    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
    	}
    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
    
    . $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)"
    
    				}
    			}
    		}
    	}
    }
    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.

    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.

  7. #7
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    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 !

  8. #8
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    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...

  9. #9
    Membre habitué
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2015
    Messages : 66
    Points : 126
    Points
    126
    Par défaut
    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

  10. #10
    Membre habitué
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2015
    Messages : 66
    Points : 126
    Points
    126
    Par défaut
    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é.

  11. #11
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    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.

  12. #12
    Membre habitué
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2015
    Messages : 66
    Points : 126
    Points
    126
    Par défaut
    Citation Envoyé par arnaudperfect Voir le message
    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.

  13. #13
    Membre habitué
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2015
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information

    Informations forums :
    Inscription : Juillet 2015
    Messages : 66
    Points : 126
    Points
    126
    Par défaut
    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

    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
                                }
                            }
                        }
    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
    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"
    
    				}
    			}
    		}
    	}
    }

  14. #14
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    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...

  15. #15
    Membre actif
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Décembre 2006
    Messages
    1 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 080
    Points : 287
    Points
    287
    Par défaut
    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 
    
    }

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Centos lister les interface réseau
    Par morgan47 dans le forum Linux
    Réponses: 7
    Dernier message: 24/10/2009, 21h02
  2. monter un partage réseau sans être administrateur
    Par martinus45 dans le forum Réseau
    Réponses: 6
    Dernier message: 04/10/2009, 14h16
  3. Lister les connexions réseau
    Par f_a_b dans le forum Web & réseau
    Réponses: 0
    Dernier message: 10/10/2008, 11h08
  4. lister les lecteurs réseau
    Par A2rem dans le forum Framework .NET
    Réponses: 1
    Dernier message: 09/08/2007, 15h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo