none
Find all computers in the domain running Mcsheild service RRS feed

  • Question

  • Hello,

    We have removed MacAfee anti-virus from our environment but it appears there are still a few machines out there in the wild that have it running.  What would be the best way to search the entire environment for any machine still running it?  I was thinking of using powershell to run the get-service command against all servers in the domain looking for the mcshield service and pipe it all to a text file.

    Can anyone help?

    Thanks.

    Thursday, April 28, 2016 5:35 PM

Answers

  • You can append to the source CSV, but I find it generally best to just create a new output file (especially since you now have all the pieces you need to do this based on output from Get-ADComputer and won't need an input CSV file in the first place).

    Import-Csv .\pcList.csv | ForEach {
    
        Get-Service -Name ALG -ComputerName $_.ComputerName
    
    } | Select MachineName,ServiceName,DisplayName,Status |
            Export-Csv .\serviceStatus.csv -NoTypeInformation


    Friday, May 6, 2016 1:28 PM

All replies

  • Hi,

    That sounds like a reasonable approach (assuming your environment isn't overly huge, that is). Use Get-ADComputer to gather your machines, ForEach-Object to loop, Test-Connection to make sure the machine is up, and then Get-Service to check. I'd use Export-Csv for output personally.

    http://ss64.com/ps/get-adcomputer.html

    http://ss64.com/ps/foreach-object.html

    http://ss64.com/ps/test-connection.html

    http://ss64.com/ps/get-service.html

    http://ss64.com/ps/export-csv.html


    Thursday, April 28, 2016 6:22 PM
  • Go ahead.  Post a question when you have one.


    \_(ツ)_/

    Thursday, April 28, 2016 6:22 PM
  • I'm going to start out simply and then add test connection and export, could you help me get this command right?

    get-adcomputer -filter * | get-service mcshield

    returns error:

    Cannot validate argument on parameter 'ComputerName'

    If I can get this working it would be a good start.

    Thursday, April 28, 2016 7:13 PM
  • Get-ADComputer returns an object 'ADComputer' which contains not only hostname, but also other AD-specific paramters. I think your attempt is almost good, but then you need to strip away all other paramters. I personally like to filter output by using Select -ExpandProperty (propertyname) so something as such:

    Get-ADComputer -Filter * | Select -expandProperty hostname | Foreach-object { Get-Service mcshield -computername $_ }

    Note that you need to check what property you really need - use Get-ADComputer 'computername' to see what it returns and then look for the query.
    • Edited by Alex Pawlak Thursday, April 28, 2016 9:48 PM
    Thursday, April 28, 2016 9:47 PM
  • Don't work so hard.  Ley PowerShell do the hard work:

    Get-ADComputer -Filter * |  
    	Foreach-object{
    		Get-Service mcshield -computername $_ .Name -ea 0
    	} 

    An alternate is to do a computed conversion:

    Get-ADComputer -Filter * | Select @{n='ComputerName';e={$_.Name}} |Get-Service mcshield  -ea 0


    \_(ツ)_/

    Thursday, April 28, 2016 10:19 PM
  • Thanks for the help to both of you.

    For some reason if I use 'ComputerName' I get no output, however if I change that to 'DNSHostName' it worked:

    Get-ADComputer -Filter * | Select -expandProperty DNSHostName | Foreach-object { Get-Service mcshield -computername $_ }

    This command results in an error for servers which are not running mcshield, and returns the information below if it finds it:

    *NOT RUNNING

    Get-Service : Cannot find any service with service name 'mcshield'.
    At line:1 char:110
    + Get-ADComputer -Filter 'Name -like "MB*"' | Select -expandProperty DNSHostNam
    e | Foreach-object { Get-Service <<<<  mcshield -computername $_ }
        + CategoryInfo          : ObjectNotFound: (mcshield:String) [Get-Service],
        ServiceCommandException
        + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.
       Commands.GetServiceCommand

    RUNNING

    Status   Name               DisplayName
    ------   ----               -----------
    Running  mcshield           McAfee McShield
    Running  mcshield           McAfee McShield
    Running  mcshield           McAfee McShield
    Running  mcshield           McAfee McShield
    Running  mcshield           McAfee McShield
    Running  mcshield           McAfee McShield

    Unfortunately it just tells me that the service is in fact running on the host which I ran the get-service command on, but it doesn't say the name of the host.  Is there a way to just disregard all the machines that return and error, and provide a list of hostnames for those that report that the service is running?

    Thanks so much for the help again.



    • Edited by dbutch1976 Friday, April 29, 2016 12:51 PM
    Friday, April 29, 2016 12:50 PM
  • You can use an if test for something like that. Here's a simplified example:

    If (Get-Service asdf -ErrorAction SilentlyContinue) {
    
        Write-Host 'Service found' -ForegroundColor Green
    
    } Else {
    
        Write-Host 'Service NOT found' -ForegroundColor Red
    
    }


    Friday, April 29, 2016 5:16 PM
  • Thanks for the reply Mike. My Powershell scripting is pretty bad as I'm sure you've guess by now, I'm getting:


    Get-Service : A positional parameter cannot be found that accepts argument '.Name'.


    Get-ADComputer -Filter * | 
    Foreach-object{
    Get-Service mcshield -computername $_ .Name -ea 0
    }
    If (Get-Service asdf -ErrorAction SilentlyContinue) {
    Write-Host 'Service found' -ForegroundColor Green
        }
    Else {
    Write-Host 'Service NOT found' -ForegroundColor Red
        }

    Friday, April 29, 2016 6:31 PM
  • You're welcome. You have a space between $_ and .Name.

    This won't do what you're expecting though. The if test is looking at the local machine only. I suggest dropping your first Get-Service command and doing the check directly in the if test.


    Friday, April 29, 2016 6:40 PM
  • I'm sorry, but I don't know how to do that. This command gives the output that I'm looking for:

    # Purpose:  To check whether a service is installed
     $sName = "MCSHIELD"
    $service = Get-Service -display $sName -ErrorAction SilentlyContinue
    If ( -not $service )
    {$sName + " is not installed on this computer. `n
    Did you really mean:  " + $sName }
    else { $sName + " is installed."
    $sName + "'s status is:  " + $service.Status }

    This works if I run it on the machine locally, but I'm not sure how to combine it with the Get-ADComputer -Filter * |   command in order to get it to run against all the computers in my domain, I just don't have the scripting knowledge to put them together without breaking it.

    Tuesday, May 3, 2016 7:02 PM
  • I'll break this down step by step, starting by getting a list of all computers called "testsvr" in AD and exporting it to csv.  This command works perfectly:

    Get-ADComputer -Filter 'Name -like "TEST*"' | Select -expandProperty DNSHostName

    However after following the steps in the link above I'm getting a numeric output rather than the hostnames that the command outputs:

    Get-ADComputer -Filter 'Name -like "TEST*"' | Select -expandProperty DNSHostName | export-csv c:\mcshield\logs\computersnofilter.csv

    Output:

    #TYPE System.String
    Length
    15
    15
    15
    15
    15
    15
    20
    20

    Thursday, May 5, 2016 1:34 PM
  • In this case you don't want to use -ExpandProperty, since you're outputting to a CSV file and need an object, not just a string:

    Get-ADComputer -Filter "Name -like 'TEST*'" |
        Select DNSHostName |
            Export-Csv .\hostnameList.csv -NoTypeInformation

    Using -ExpandProperty is useful if you were outputting to a text file instead.


    Thursday, May 5, 2016 1:39 PM
  • Perfect, on to set two, checking if the computers are online or not using test-connection, here's what I've got:

    Get-Content .\1allcomps.csv | ForEach-Object {
        if(Test-Connection -ComputerName $_ -Quiet -Count 1) {
            New-Object -TypeName PSCustomObject -Property @{
                VMName = $_
                'Ping Status' = 'Ok'
            }
        } else {
            New-Object -TypeName PSCustomObject -Property @{
                VMName = $_
                'Ping Status' = 'Failed'
            }
        }
    } | Export-Csv -Path 2Ping.csv -NoTypeInformation

    The only computers in the output are coming up with ping status 'failed' even for computers which I know are pingable.  Any idea how I can troubleshoot?

    Thursday, May 5, 2016 2:24 PM
  • Since you're using a CSV file as input, you'll need to reference the proper header when using the $_ variable:

    Import-Csv .\pingMe.csv | ForEach {
    
        If (Test-Connection -ComputerName $_.ComputerName -Count 1 -Quiet) {
    
            [pscustomobject]@{
                VMName = $_.ComputerName
                Alive = $true
            }
    
        } Else {
    
            [pscustomobject]@{
                VMName = $_.ComputerName
                Alive = $false
            }
    
        }
        
    } | Export-Csv .\pingResults.csv -NoTypeInformation

    My input CSV has a header of ComputerName.


    Thursday, May 5, 2016 2:30 PM
  • The header from my csv file is 'DNSHostName' so I changed $_.computername to $_.DNSHostname. This script appears to run, but again the output is not what I expect. Here's the code:

    Import-Csv .\1allcomps.csv | ForEach {

        If (Test-Connection -ComputerName $_.DNSHostName -Count 1 -Quiet) {

            [pscustomobject]@{
                VMName = $_.DNSHostName
                Alive = $true
            }

        } Else {

            [pscustomobject]@{
                VMName = $_.DNSHostName
                Alive = $false
            }

        }
       
    } | Export-Csv .\2ping.csv -NoTypeInformation

    Here is the output:


    IsReadOnly


    IsFixedSize


    IsSynchronized


    Keys


    Values


    SyncRoot


    Count


    FALSE


    FALSE


    FALSE


    System.Collections.Hashtable+KeyCollection


    System.Collections.Hashtable+ValueCollection


    System.Object


    2

    Thursday, May 5, 2016 2:42 PM
  • You must still be on v2. I recommend upgrading at some point.

    Import-Csv .\pingMe.csv | ForEach {
    
        If (Test-Connection -ComputerName $_.ComputerName -Count 1 -Quiet) {
    
            $props = @{
                VMName = $_.ComputerName
                Alive = $true
            }
    
        } Else {
    
            $props = @{
                VMName = $_.ComputerName
                Alive = $false
            }
    
        }
    
        New-Object PsObject -Property $props
        
    } | Select VMName,Alive |
            Export-Csv .\pingResults.csv -NoTypeInformation


    Thursday, May 5, 2016 2:56 PM
  •  I'm almost there, I manually pruned out the CSV file so that it is only machines which are online and responding, the header is DNSHostName.  Now when I run the following command:

    Import-Csv .\3AllAdComps.csv | ForEach {
        Get-Service mcshield -ComputerName $_.DNSHostName
        }

    I'm getting:

    Status   Name               DisplayName                          
    ------   ----               -----------                          
    Running  mcshield           McAfee McShield                      
    Running  mcshield           McAfee McShield 

    This is almost perfect, you told me how to export the result to csv, how do I append only to a new heading called McShield?  Can I append the source .csv file I'm importing in the script so that it just has two headers, DNSHostName, McShield?  Or should I create a new CSV file for the output?

    Thursday, May 5, 2016 7:18 PM
  • You can append to the source CSV, but I find it generally best to just create a new output file (especially since you now have all the pieces you need to do this based on output from Get-ADComputer and won't need an input CSV file in the first place).

    Import-Csv .\pcList.csv | ForEach {
    
        Get-Service -Name ALG -ComputerName $_.ComputerName
    
    } | Select MachineName,ServiceName,DisplayName,Status |
            Export-Csv .\serviceStatus.csv -NoTypeInformation


    Friday, May 6, 2016 1:28 PM
  • It generates errors for all the servers which don't have the mcshield service running, but the important thing is that the resulting output file is a list of all servers which have the service running which is exactly what I need.

    Huge thanks for your help!

    Friday, May 6, 2016 1:32 PM
  • Cheers, you're very welcome.

    And just for the future, here's how I'd have tackled this:

    Get-ADComputer -Filter * | ForEach-Object {
    
        $computerName = $_.Name
    
        If (Test-Connection -ComputerName $computerName -Count 1 -Quiet) {
    
            If ($service = Get-Service GearSecurity -ComputerName $computerName -ErrorAction SilentlyContinue) {
    
                Write-Host "Service found on $computerName" -ForegroundColor Green
                $service 
    
            } Else {
    
                Write-Host "Service NOT found on $computerName" -ForegroundColor Red
    
            }
    
        }
    
    } | Select MachineName,ServiceName,DisplayName,Status | 
            Export-Csv .\serviceStatus.csv -NoTypeInformation

    This gives you a visual indicator in the console of which machines do and do not have the service and an output file with the machines that do have the service installed.


    Friday, May 6, 2016 1:38 PM