Question Droit en lecture sur un PC distant

Plus d'informations
il y a 14 ans 10 mois #9643 par FLORENT
Bonjour a tous,

Bon pour finaliser un programmes il me manque une seule chose : Pouvoir vérifier si j'ai les droits en lecture sur un PC distant.

Pourquoi ?

Mon programme vise a une chose : Établir la liste des Softwares installes sur une liste de PC. Il gère le fait qu'un PC ne soit pas accessible car il n'est pas connecte au réseau. Le souci c'est que si je ne vérifie pas aussi si j'ai les droits d’accès en lecture sur un PC il me rajoute dans mon résultat final le nom du PC qui aurait du être analyse avec la liste des softwares du PC précédemment analyse.

Voici mon code il est un peu brouillon car je ne sais pas encore trop gérer les fonctions, les variables locales etc.. en Powershell :

[code:1]#Import list of computers
$COMPUTERS = @()
$COMPUTERS += get-content ListePCTest1.txt
#Computer for which the ping don't work
$textFail = @()
$textFail += \"Computer List\"
#Computer for which the ping work
$textSuccess = @()
$textSuccess += \"Computer List\"
#Computer for which the ping don't work
$textFailAccess = @()
$textFailAccess += \"Unfounded Computer\"
#If the ping works
\"true\" > works.txt
#List of computers and their installed software
$liste = @()
FOREACH ($PC in $COMPUTERS)
{
#we try a ping
$ping = New-Object Net.NetworkInformation.Ping
$PingResult = $ping.send($PC)
trap
{
\"false\" > works.txt
continue
}
if ((Get-Content works.txt) -eq \"true\"«»)
{
#If ping works, the pc is send to success list
if ($PingResult.Status.Tostring() -eq \"success\"«»)
{
$textSuccess += $pc
\"true\" > works.txt
}
#If ping doesn't work, the pc is send to fail list
else
{
$textFail += $pc
\"false\" > works.txt
}
}
else
{
$textFailAccess += $pc
}
if ((Get-Content works.txt) -eq \"true\"«»)
{
$PC


# Branch of the Registry
$Branch='LocalMachine'

# Main Sub Branch you need to open
$SubBranch=\"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\"

$registry=[microsoft.win32.registrykey]::OpenRemoteBaseKey('Localmachine',$PC)
$registrykey=$registry.OpenSubKey($Subbranch)
$SubKeys=$registrykey.GetSubKeyNames()

# Drill through each key from the list and pull out the value of
# “DisplayName” – Write to the Host console the name of the computer
# with the application beside it

Foreach ($key in $subkeys)
{
$exactkey=$key
$NewSubKey=$SubBranch+\"\\\"+$exactkey
$ReadUninstall=$registry.OpenSubKey($NewSubKey)
$Value=@()
$Value += $ReadUninstall.GetValue(\"DisplayName\"«»)
#WRITE-HOST $computername, $Value
Foreach ($soft in $Value)
{
if ($soft -ne $null)
{
$liste += $PC + \" \" + $soft
}
}

}
}
\"true\" > works.txt

}
$textSuccess > sucess.txt
$textFail > fail.txt
$textFailAccess > failAccess.txt
$liste > pcEtSoftList.txt[/code:1]

Message édité par: toaster, à: 13/05/11 04:20<br><br>Message édité par: toaster, à: 13/05/11 05:18

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 14 ans 10 mois #9671 par Matthew BETTON
Bonjour,

il me rajoute dans mon résultat final le nom du PC qui aurait du être analyse avec la liste des softwares du PC précédemment analyse.


A la lecture de ton code, ta variable '$liste' est utilisée si et seulement si la machine a répondu au ping... Sinon tu passes à la machine suivante.

Or cette variable $liste n'est pas ré initialisée lors de ce passage à la machine suivante... Et c'est là qu'est l'os, hélas ! ;)

Si tu déplaces cette initialisation

[code:1]$liste = @()[/code:1]

juste après

[code:1]FOREACH ($PC in $COMPUTERS)
{[/code:1]

ou dans tous les cas juste avant ton bloc

[code:1]if ((Get-Content works.txt) -eq \&quot;true\&quot;«»)[/code:1]

je pense que cela ira mieux

Sinon, tu peux reprendre ce qui est dit par Laurent Dardenne dans ce poste pour ce qui concerne les lignes de codes telles que :

[code:1]$COMPUTERS = @()

$COMPUTERS += get-content ListePCTest1.txt[/code:1]

Cela peut s'écrire plus simplement :

[code:1]$COMPUTERS = get-content ListePCTest1.txt[/code:1]

Pour ce que tu utilises comme solution pour contrôler si la machine est présente sur le réseau (cf. ping), je pense qu'il y a plus simple que d'utiliser un trap et de passer par un fichier \&quot;flag\&quot; contenant la valeur true ou false...

Je ne comprends pas l'utilité de passer par le fichier 'works.txt'.

Tu pourrais du coup simplifier ton script en supprimant des blocs \&quot;if / else\&quot; ...

Tu tests déjà si la machine a répondu au ping ici

[code:1]if ($PingResult.Status.Tostring() -eq \&quot;success\&quot;«») [/code:1]

Dans ce bloc 'if' tu pourrais directement effectuer les opérations de lecture du registre...

@ +

Matthew

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 14 ans 10 mois #9672 par Matthew BETTON
Ta méthode pour accéder au registre d'une machine distante ne nécessite pas d'authentification particulière : tu utilises implicitement le compte avec lequel ton script est exécuté.

Dans ce cas, si tu souhaites tester si tu as les droits, avant de procéder à la lecture du registre, une solution :

[code:1]try{
Get-WmiObject -Class Win32_BIOS -Namespace 'root\cimv2' -ComputerName $PC -ErrorAction Stop
}
catch [System.UnauthorizedAccessException]{
Write-Error \&quot;Accès refusé pour $PC\&quot;
}
catch{
Write-Error \&quot;Une erreur s'est produite lors de l'accès à la classe Win32_BIOS sur $PC : $($_.Exception.Message)\&quot;
}[/code:1]

On \&quot;tombe\&quot; dans le premier 'Catch' si une exception du type 'System.UnauthorizedAccessException' est levée... c'est à dire \&quot;si tu n'as pas les droits sur la machine distante\&quot; d'accéder à la classe 'Win32_Bios'.

Sinon, pour lire le registre à distance en spécifiant un 'Credential' spécifique (authentification explicite) une solution est de passer par la classe StdRegProv, via WMI : utiliser dans ce cas la Cmdlet 'Get-WmiObject' et son paramétre '-Credential', comme dans l'exemple donné ici .

Pour récupérer des informations sur la Cmdlet 'Get-WmiObject' :

[code:1]Get-Help Get-WmiObject[/code:1]

Comme le dit \&quot;MichalGajda\&quot;, on aurait pu passer par la classe WMI 'Win32_Product', mais elle ne permet de lister que les applications installées via le MSI Installer. J'ajouterai même que cette classe n'est pas disponible par défaut sur des machines Windows 2003 Server (il s'agit d'un composant Windows optionnel).

En espérant que ces informations t'aideront ;)

@ +

Matthew

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 14 ans 10 mois #9673 par FLORENT
Bon d'abord merci pour vos réponses.


Le problème concernant la liste que j'ai en résultat est réglé. Mais maintenant je souhaiterai avoir la liste des PC sur lesquels je n'ai pas eu l'acces.

Concernant le trap c'est un peu du bricolage je l'avoue mais il vient du fait que quand j'ai essaye de stock une valeur dans une variable a l’intérieur du trap, een sortant du trap la variable reprend la valeur qu'elle avait avant le trap.

Et merci pour l'optimisation des if/else je n'y avait pas fait attention :)

Et pour le try catch je rêve de pouvoir l'utiliser... mais je suis sous powershell V1<br><br>Message édité par: toaster, à: 18/05/11 07:29

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.040 secondes
Propulsé par Kunena