2015-04-23 1 views
0

Je tente d'obtenir cette boucle ForEach pour rechercher une installation de logiciel spécifique sur un ordinateur en utilisant une recherche de registre. Pour une raison quelconque, il est seulement trouver un et pas les deux autres, même si je sais et je peux voir qu'ils sont installés. Qu'est-ce qu'un manqué.Logiciel PowerShell Search installé

Clear-Host 
$Computers = hostname 

$array = @() 

foreach($pc in $computers){ 

    $computername=$pc.computername 

    #Define the variable to hold the location of Currently Installed Programs 

    $UninstallKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 

    #Create an instance of the Registry Object and open the HKLM base key 

    $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername) 

    #Drill down into the Uninstall key using the OpenSubKey Method 

    $regkey=$reg.OpenSubKey($UninstallKey) 

    #Retrieve an array of string that contain all the subkey names 

    $subkeys=$regkey.GetSubKeyNames() 

    #Open each Subkey and use GetValue Method to return the required values for each 


    ForEach($Key in $subkeys) { 
     $thisKey=$UninstallKey+"\\"+$key 

     $thisSubKey=$reg.OpenSubKey($thisKey) 
     #If found set variable to True for used in report 

      if (($thisSubKey.GetValue("DisplayName") -like "CCleaner")) {Write-Host "CCleaner = True"} 
      Else {Write-Host = " False"} 

     if (($thisSubKey.GetValue("DisplayName") -like "*7-Zip*")) {Write-Host "7Zip = True"} 
      Else {Write-Host = " False"} 

     if (($thisSubKey.GetValue("DisplayName") -like "*.NET Framework*")) {Write-Host ".NET = True"} 
      Else {Write-Host = " False"} 


    } 

} 

Il trouve DotNet et son égale vrai, mais le 7-Zip et sont également installés CCleaner et à la place que je cherche. J'ai regardé ce code pendant un moment maintenant et je ne vois pas pourquoi.

Je sais que j'ai défini les ordinateurs pour nom d'hôte, je vais changer pour un fichier avec une liste d'ordinateurs. C'est juste pour le test en ce moment.

Merci d'avance.

+0

OS 64 bits? Les chances sont que vous avez une application 32 bits et ils sont situés dans le WoW6432Node. Votre instruction CCLeaner '-like' n'a aucun caractère générique. Je suggère d'utiliser '-match' au lieu de' -like' et de supprimer les astérisques. Cela pourrait bien résoudre votre problème. Puisque le nom d'affichage de 7-Zip commence par 7-Zip, je ne me souviens pas si '-like' le trouvera si vous placez un astérisque devant le texte. match est mieux que comme à mon avis quand il peut être utilisé. – TheMadTechnician

+0

Il s'agit d'un système d'exploitation 64 bits, je devrais peut-être répondre aux deux dans ce cas, j'ai ajouté les caractères génériques aux noms et supprimé l'instruction else. Jusqu'à présent, je pense, je vais continuer à tester les logiciels faux pour voir si les rapports en retour comme il se doit. Merci pour la réponse. –

Répondre

3

Je pense que toutes vos instructions If pourraient être remplacées par une instruction Switch qui fonctionnerait plus vite et mieux (un appel pour obtenir la valeur du registre distant au lieu de 3), plus il peut correspondre à la regex. Pensez à supprimer tous les trois de vos If déclarations et les remplacer par:

Switch -Regex ($thisSubKey.GetValue("DisplayName")){ 
    "CCleaner" {Write-Host "CCleaner = True";continue} 
    "7-Zip" {Write-Host "7-Zip = True";continue} 
    "\.Net Framework" {Write-Host ".Net Framework = True"} 
} 

Cela devrait faire efficacement la même chose que tous vos If déclarations

Edit: Comment obtenir les 32 touches de bits. .. Eh bien, vous avez déjà le code pour obtenir des choses à partir du registre, juste virer sur une deuxième partie après le commutateur essentiellement avec un chemin modifié. Mieux encore, faisons une seule liste de toutes les applications installées à partir des valeurs DisplayName, ajoutons toutes celles de la section Wow6432Node à cette liste, puis exécutons la liste entière à travers le Switch. Maintenant, je suppose que, puisque vous référencez une propriété computername dans votre code, vous importez un fichier CSV et faites une boucle à travers cela? Je l'espère, je me suis basé sur ça. Donc, cela va parcourir les ordinateurs dans un CSV où le nom de l'ordinateur est stocké dans une propriété computername. Il ajoutera 3 nouvelles propriétés à chaque ordinateur: CClean, 7-Zip et .Net Framework. Il les définit tous comme $false par défaut. Ensuite, il tire les listes de logiciels, et s'il trouve l'un de ceux-ci, il change cette propriété à $true.

Clear-Host 
$Computers = @($(new-object PSObject -prop @{'ComputerName' = $env:COMPUTERNAME})) 
##Computers = Import-CSV 'C:\Path\To\SCCMVerify.csv' 

$array = @() 

for($i = 0; $i -lt $computers.count;$i++){ 

    $computername=$computers[$i].computername 
    Add-Member -InputObject $computers[$i] -NotePropertyName 'CCleaner' -NotePropertyValue $false 
    Add-Member -InputObject $computers[$i] -NotePropertyName '7-Zip' -NotePropertyValue $false 
    Add-Member -InputObject $computers[$i] -NotePropertyName '.Net Framework' -NotePropertyValue $false 



    #Define the variable to hold the location of Currently Installed Programs 

    $UninstallKey="SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 
    $Uninstall32Key="SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall" 

    #Create an instance of the Registry Object and open the HKLM base key 

    $reg=[microsoft.win32.registrykey]::OpenRemoteBaseKey('LocalMachine',$computername) 

    #Drill down into the Uninstall key using the OpenSubKey Method 

    $regkey=$reg.OpenSubKey($UninstallKey) 
    $reg32key=$reg.OpenSubKey($Uninstall32Key) 

    #Retrieve an array of string that contain all the subkey names 

    $subkeys=$regkey.GetSubKeyNames() 
    $sub32keys=$reg32key.GetSubKeyNames() 

    #Open each Subkey and use GetValue Method to return the required values for each, compile that in a list 

    $applications = $subkeys|ForEach{$reg.OpenSubKey("$UninstallKey\\$_").GetValue('DisplayName')} 
    $applications += $sub32keys|ForEach{$reg.OpenSubKey("$Uninstall32Key\\$_").GetValue('DisplayName')} 

    #Search all applications for matching software 
    Switch -Regex ($applications) { 
     "CCleaner" {Write-Host "CCleaner = True";$Computers[$i].CCleaner = $true ;continue} 
     "7-Zip" {Write-Host "7-Zip = True";$computers[$i].'7-Zip' = $true;continue} 
     "\.Net Framework" {Write-Host ".Net Framework = True";$Computers[$i].'.Net Framework' = $true}   
    } 

} 
+0

Doux, ça a l'air bien. Je vais essayer et plus de logiciels. C'est essentiellement pour une séquence de tâches dans SCCM à la fin de la construction pour me faire savoir si tous les logiciels ont été installés. –

+0

Aussi juste pensé, pourrais-je l'obtenir pour vérifier le Wow6432Node –

+0

Ok, j'ai rediffusé un script entier, modifié pour vérifier les deux clés. J'ai fait d'autres modifications que vous pouvez prendre ou laisser. – TheMadTechnician