Solved

how to check .net version installed on 500 workstations

Posted on 2014-10-24
9
307 Views
Last Modified: 2014-11-03
I work for a company with a lot of workstations and we currently use IBM BigFix to query worksations for their .Net framework version. My question is Is there another way to query workstations besides using BigFix or Tanium? All I want to do is check each workstation for .Net 4.0 and above and report all the names of the workstations that does not have .Net 4.0 or above.
0
Comment
Question by:matthew phung
  • 3
  • 2
  • 2
  • +2
9 Comments
 
LVL 6

Expert Comment

by:Wylie Bayes
ID: 40403166
What OS are the workstations?  Windows 7 or higher?
0
 
LVL 33

Expert Comment

by:Dave Howe
ID: 40403309
Its certainly possible, don't have any code on hand to do it though.  I can think of two ways immediately that you could achieve this.  The first is a bit crude (actually, a lot!) , but has the benefit of being easy to understand and very short indeed :)

Both answers rely on the fact that the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP has one subkey per installed framework - so reading that on each machine in turn would give you the info you need. Further, all dotnet frameworks from 4.0 onwards use a registry key of "v4" - so checking for HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4 would tell you have 4.0 *or better* without investigating further, which is probably good enough

Now, on to the crude method :)

Assuming you have your users logging into a domain, you can establish a network share on a server that is world writable, and have each user login script execute the relatively simple command:

RegEdit /a %COMPUTERNAME%.reg "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP"

(placing the share path in front of the computername variable so that it writes to the network)

as %COMPUTERNAME% contains the name of the computer (logically enough) that should give you a separate file for each workstation, containing the registry keys under the key indicated. Simply wait a few days, then you should have the info you need (although not really in a tidy list without further processing)

For a less crude method - there is a powershell module (formerly on the ms site, now on codeplex) that lets you query the registry of a remote machine.  You could logically write a powershell script to check the registry key above for a single named remote machine (passed as an argument) then you need to call that script once per machine, and record the result.

With 500 workstations though, iterating though the set (particularly if you aren't going to know what IP they might have or if they are turned on at any given moment) could be interesting.  You can also use WMI (although its more awkward to code for than a dedicated PS module) - both methods would have the benefit of outputting a tidy list.  Combining this with the first method, you could run (say) vbscript in the login script, extract the info you need locally, then write it to a database or similar on a server - but that's a fair bit of work to code up (of course, if you wanted to re-use the technique for other checks, then it might be worth investing time coding a solution so that you have an example to modify when you have something you want and can't get easily by any other method)
0
 
LVL 6

Expert Comment

by:Wylie Bayes
ID: 40403349
This can be easily achieved with powershell.  If the workstations are Windows 7 or higher.
0
 

Author Comment

by:matthew phung
ID: 40403407
Thank you Dave for your detailed answer. I am not too familiar with PowerShell so is there a good tutorial/resource you guys recommend. I am very strong in C# and VB.Net. I appreciate your help, guys
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 6

Accepted Solution

by:
Wylie Bayes earned 500 total points
ID: 40403419
Gather Machine IP's via LDAP / Pulling from OU and machine objects:

<#          .SYNOPSIS
        AD Searcher unites with .Net DNS object to quickly provide IPs by organizations
            for asset list import to Nessus.
         .DESCRIPTION
            Collects IP addresses for Active Directory computer objects by OU.
       .PARAMETER
         .INPUTS
         .OUTPUTS
         .NOTES
          ONLY MODIFY THE ADSI SEARCHER STRING'S OUs.
            Name: Get-PMOIPs
        Author: Steve Jarvi
        DateCreated: 9 April 2014
         .EXAMPLE
          
          FOR Changing Machine OUs: "LDAP://OU=SomeOU,OU=SomeOU,OU=SomeOU,OU=SomeOU,DC=SomeDC,DC=SomeDC,DC=SomeDC,DC=COM"
    #>

$searcher = New-Object System.DirectoryServices.DirectorySearcher $([ADSI] "LDAP://OU=SomeOU,OU=SomeOU,OU=SomeOU,OU=SomeOU,DC=SomeDC,DC=SomeDC,DC=SomeDC,DC=COM")
$searcher.pagesize = 1
$searcher.filter = ("(objectCategory=computer)")
$array = @($($searcher.findall()) | % {$_.properties.cn})

@(for ($i=0;$i -lt $array.count; $i++){
            Try {
            ([System.Net.Dns]::GetHostAddresses("$($array[$i])")).IPAddressToString
            Write-Host "Forward lookup entry found for: $($array[$i])" -Fore green
            }
            Catch {
            Write-Host "There is no forward lookup DNS entry for: $($array[$i])" -Fore red
            }
      }) > machine_ips.txt

get-software function (Can be tuned for just ".net" frameworks)

Function Get-Software{
    <# .SYNOPSIS
        Gets the software applications on a remote computer.
         .DESCRIPTION
        This function interrogates the remote registry for installed
            software products.
        It then returns an array of powershell objects that can be sorted
            and parsed.
       
        Optionally, you can provide a product name that will filter
            applications based on displayname before they are returned, thus reducing the typing
            needed to get specific results.
            .PARAMETER computer
        The name of the computer to retrieve a software list from.
            .PARAMETER product
        The partial name of a software application to search for.
            .INPUTS
            .OUTPUTS
            .NOTES
        Name: Get-Software
        Author: Geoffrey Guynn
        DateCreated 9 Aug 2011
    .EXAMPLE
        Get-Software -computer "computer" -command "Adobe"
        Returns all instances of Adobe software on the computer.
    #>

    [cmdletbinding(
        SupportsShouldProcess = $True,
        DefaultParameterSetName = "process",
        ConfirmImpact = "low"
    )]
    param(
        [ValidateNotNullOrEmpty()]
        [string]$Computer
        ,
        [string]$Product
    )
      
    if (TestRemoteAdmin $Computer){
        #Get Architechture Type of the system
        #$OSArch = (Gwmi -computer $Computer win32_operatingSystem).OSArchitecture
         $OSArch = (Gwmi -computer $Computer win32_operatingSystem).caption
        if ($OSArch -like "*64*") {$Architectures = @("32bit","64bit")}
        else {$Architectures = @("32bit")}
        #Create an array to capture program objects.
        $arApplications = @()
        foreach ($Architecture in $Architectures){
            #We have a 64bit machine, get the 32 bit software.
            if ($Architecture -like "*64*"){
                #Define the entry point to the registry.
                $strSubKey = "SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
                $SoftArchitecture = "32bit"
                $RegViewEnum = [Microsoft.Win32.RegistryView]::Registry64
            }
            #We have a 32bit machine, use the 32bit registry provider.
            elseif ($Architectures -notcontains "64bit"){
                #Define the entry point to the registry.
                $strSubKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
                $SoftArchitecture = "32bit"
                $RegViewEnum = [Microsoft.Win32.RegistryView]::Registry32
            }
            #We have "64bit" in our array, capture the 64bit software.
            else{
                #Define the entry point to the registry.
                $strSubKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
                $SoftArchitecture = "64bit"
                $RegViewEnum = [Microsoft.Win32.RegistryView]::Registry64
            }
            #The standard routine to get software.
 
#************************************************************************
            #Create a remote registry connection to the server.
            $remRegistry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $Computer, $RegViewEnum)
            #Open the entry point.
            $remKey = $remRegistry.OpenSubKey($strSubKey)
            #Get all subkeys that exist in the entry point.
            $remSoftware = $remKey.GetSubKeyNames()
            #Loop through the applications and capture data.
            foreach ($remApplication in $RemSoftware){
                $remProgram = $remRegistry.OpenSubKey("$strSubKey\\$remApplication")
                $strDisplayName = $remProgram.GetValue("DisplayName")
                if ($strDisplayName){
                    #Get a list of all available properties for the program.
                    $arProperties = $remProgram.GetValueNames()
                    #Create a custom object for this program.
                    $objApplication = New-Object System.Object
                    #Write-Host "`n"
                    foreach ($strProperty in $arProperties){
                        #Get the value associated with the current property.
                        $strValue = [string]($remProgram.GetValue($strProperty))
                        if ($strValue){
                            #If the property has a value but no name, then it is the default property.
                            if (!$strProperty){
                                $objApplication | Add-Member -type NoteProperty -Name "(Default)" -Value $strValue
                            }
                            #The property has a value and a name, assign them both as a new property on the object.
                            else{
                                $objApplication | Add-Member -type NoteProperty -Name ([string]$strProperty) -Value $strValue
                            }
                        }
                        #Write-Host $strValue ": "
                                    $remProgram.GetValue($strValue)
                    }
                    #Add a final property to denote the software architecture type.
                    $objApplication | Add-Member -type NoteProperty -Name "Architecture" -Value $SoftArchitecture
                    #Add the last application to the array of programs.
                    $arApplications += $objApplication
                }
            }
            #Sort the array by each object's displayName.
        }
        if ($Product){
            $objApplication = $arApplications | ? {$_.DisplayName -Like "*$Product*"}
            return $objApplication
        }
        $arApplications = $arApplications | Sort-Object -property Architecture,DisplayName
        return $arApplications
    }
    return $null
}
0
 
LVL 7

Expert Comment

by:Stampel
ID: 40403856
Are you able to run a DOS command remotely on all the 500 workstations ?
It could search for the .net string to detect if the .NET is installed or not.
Would that be sufficient ? If Yes i can provide the command i have somewhere.
0
 

Author Comment

by:matthew phung
ID: 40404170
Wiley, Thank you for the detailed reply again. I will definitely play around with the code.

Stampel, I  might be able to run DOS remotely so can you provide me the command? Once again, thank you everyone for your help
0
 
LVL 4

Expert Comment

by:FrankCrast
ID: 40404172
Some of this may already be covered before, but Microsoft has a good MSDN article that helps summarize how to do this: http://msdn.microsoft.com/en-us/library/hh925568(v=vs.110).aspx

In BigFix, you should be able to create a simple fixlet to search for the reg key and values you need -- e.g., HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP (from article above). Fixlets are much easier than writing custom scripts in my opinion. You may as well use BF if you already have it, to keep it simple.

IBM has lots of sample solutions to help with this, for instance this example to search for a value in a reg key:
https://www.ibm.com/developerworks/community/forums/html/topic?id=d64a6ad3-2664-4cc2-8389-c534668bf033

Hope this helps.
0
 
LVL 7

Expert Comment

by:Stampel
ID: 40404722
Ok here is the command to return any installed software matching ".NET"

C:\>wmic product get name | findstr .NET
result for me =>
Microsoft .NET Framework 4.5.1 (EN)
Microsoft .NET Framework 4.5.1
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

How can you create a game plan that lets you focus on special projects instead of running from cubicle to cubicle every day and feeling like you’ve accomplished nothing? Try these strategies for prioritizing your tasks, offloading what you can, and …
A brand new malware strain was recently discovered by security researchers at Palo Alto Networks dubbed “AceDeceiver.” This new strain of iOS malware can successfully infect non-jailbroken devices and jailbroken devices alike.
This video discusses moving either the default database or any database to a new volume.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now