Troubleshooting ConfigMgr 2012 Client Migration using Powershell (Part 5)

In this post we’ll look at troubleshooting WMI errors.  Fixing every potential WMI issue is beyond the scope of this blog series, but what we can do it run the WMIDiag utility on the client machine, and this is very helpful to diagnose potential issues with WMI.  The report generated by WMIDiag contains advice on how to resolve the WMI errors it finds.

If ConfigMgr cannot install the client due to a WMI error, this should be reported in the CCM.log on the Site Server. Check there to find the exact error code. The error code may or may not indicate an actual WMI issue, as described in the WMIDiag documentation:

0x800410xx and 0x800440xx are WMI errors. These error codes mean that a specific WMI operation failed. This could be due insufficient privileges to perform the WMI requested operation; due to the nature of the request itself (for example, no WMI rights, bad WQL query); or due to a WMI infrastructure issue, such as CIM or WMI DCOM registration preventing a provider from being loaded.

0x8007xxxx are Win32 errors, not WMI errors. WMI may return these types of error due to an external failure (for example, DCOM security).

0x80040xxx are pure DCOM errors, not WMI errors. WMI may return these types of error due to an external failure (for example DCOM configuration).

0x80005xxx are ADSI errors (LDAP), not WMI errors. WMI may return these types of errors due to an external failure, such as an Active Directory access failure when using the WMI Active Directory providers.

If a true WMI error is suspected, we can run WMIDiag on the machine using Powershell.

Prepare the WMIDiag Files

Download WMIDiag from Microsoft and place the 3 files on a network share.  Since WMIDiag must be run locally, the script will copy the WMIDiag.vbs to the remote machine and start it.

Run the Powershell Script

Run the Powershell Script below entering the following variables:
$ComputerName = the name of the remote computer to run WMIDiag on
$CMTrace = The path to the CMTrace utility used for viewing the resulting log file.
$WMIDiagVBS = Enter the path to the WMIDiag.vbs on the file share
$ClientLogs = Enter a remote fileshare to copy the client logs to

The script will take some time to complete. When the WMIDiag has finished, it creates 3 files on the client:

  • Text file. This contains a summary of the health of the WMI.
  • Log file. This contains the full output of the WMIDiag tool.
  • CSV file. This contains a summary that can be imported into the master WMIDiag.csv file to view statistics for multiple machines

The script will copy these files from the client to the file share, then open the text file using the CMTrace utility for easy viewing.

The Powershell Script

<#
This script will run WMIDiag on a remote machine and opens the text report with CMTrace to review the results.
#>
$ComputerName = "DB-MyLaptop"
$CMTrace = "C:\Program Files (x86)\ConfigMgr 2012 Toolkit R2\ClientTools" # Path to CMTrace.exe on local computer

$WMIDiagFolder = "\\$ComputerName\c$\WMIDiag"
$WMIDiagLogsFolder = "\\$ComputerName\c$\WMIDiag\Logs"
$WMIDiagVBS = "\\PS1sccm-01\RemoteFiles\WMIDiag\WMIDiag.vbs"
$ClientLogs = "\\PS1sccm-01\ClientLogs\$computername"

# Test if WMIDiag and Logs directories exist, if not create them
cls
Write-Host "Creating local directories if needed..."
If (Test-Path $WMIDiagFolder)
{}
else
{
New-Item -Path $WMIDiagFolder -ItemType Directory | Out-Null
}

If (Test-Path $WMIDiagLogsFolder)
{}
else
{
New-Item -Path $WMIDiagLogsFolder -ItemType Directory | Out-Null
}

# Copy WMIDiag.vbs to local machine and run it

Copy-item $WMIDiagVBS $WMIDiagFolder
write-host "Running WMIDiag on $Computername. This will take some time!" -ForegroundColor Yellow
Invoke-Command -ComputerName $computername -ScriptBlock `
{ `
cscript c:\WMIDiag\WMIDiag.vbs Silent NoEcho LogFilePath=C:\WMIDiag\Logs `
}

# Copy the resulting files to a server location

If (Test-Path $ClientLogs)
{}
else
{
New-item $ClientLogs -itemtype Directory | Out-Null
}
Write-Host "Copying logs to server..."
copy-item $WMIDiagLogsFolder $ClientLogs -recurse -ErrorAction SilentlyContinue

# Open text report

Write-Host "Opening text report.."
$Item = Get-Item -Path "$ClientLogs\Logs\*.txt" | Select Name
$Item = $Item.Name
& "$CMTrace\CMTrace.exe" "$ClientLogs\Logs\$Item"

Repairing WMI

Some advise to delete and recreate the WMI repository, and this will generally fix a WMI issue, however it can affect other applications, so it’s recommended to be a last resort.  A more friendlier way to repair the WMI is to use Roger Zander’s SCCM Client Center, which has a Repair WMI option, and in the 2012 version it works even when you cannot connect to WMI on the machine because it uses winRM.

Here’s some useful articles for WMI repairs:

http://blogs.technet.com/b/askperf/archive/2009/04/13/wmi-rebuilding-the-wmi-repository.aspx

http://blogs.technet.com/b/configmgrteam/archive/2009/05/08/wmi-troubleshooting-tips.aspx

That’s it for now! Hopefully these posts will help you troubleshoot and fix many of the common issues that occur with ConfigMgr client upgrades.

Troubleshooting ConfigMgr 2012 Client Migration using Powershell (Part 4)

In this post, we’ll look at another cause of ConfigMgr client upgrade failure – the SMS Task Sequence Agent service is running.  It can sometimes happen that a task sequence gets ‘stuck’ and never completes, but the SMS Task Sequence Agent service (smstsmgr) is started and never stopped.  Usually I have found that it ‘freezes’ because it is waiting for software updates to pause before it can continue, and for some reason that doesn’t happen.  A similar issue is described in this post: http://setspn.blogspot.co.uk/2013/07/sccm-task-sequence-software-updates.html?sm_au=iVV7Sp7LVprV5k7F.  Usually I use the ‘reset the Paused SW distribution cookie’ option in Roger Zander’s SCCM Client Center to remedy that.

If the SMS Task Sequence Agent service is running when the ConfigMgr client installation process attempts to uninstall the previous client, it will fail, and stop the entire process.

Symptoms

This is how to detect this problem:

  • The ccmsetup.exe and associated SCCM client files are all successfully downloaded to the client, the ccmsetup service is started but the installation fails
  • The ccmsetup.log contains a line near the end that says ‘installation failed with error code 1603‘. Error code 1603 is ‘fatal error during installation’.
  • The client.msi_uninstall.log contains a line like this: ERROR: Failed to stop the ‘smstsmgr’ service, hr=8007041c

The following Powershell script can be run against a machine where to identify if it has this problem.  It will search the log files for the error string, and report if it finds it or not.


<#
Ths script searches the client.msi_uninstall.log on a remote machine to identify if the "ERROR: Failed to stop the 'smstsmgr' service" line is present in the log.
Requires admin rights to remote machine
#>

$ComputerName = "DB-MyLaptop"

$tsmanager = select-string -path \\$ComputerName\C$\Windows\ccmsetup\Logs\client.msi_uninstall.log -pattern "ERROR: Failed to stop the 'smstsmgr' service" -allmatches –simplematch
if ($tsmanager -eq $true)
{
write-host "The error 'Failed to stop the 'smstsmgr' service' IS present in the client.msi_uninstall.log on $ComputerName. Kill the tsmanager.exe process on the machine before attempting SCCM client upgrade." -ForegroundColor Yellow
}
if ($tsmanager -eq $null)
{
write-host "The error 'Failed to stop the 'smstsmgr' service' is NOT present in the client.msi_uninstall.log on $ComputerName."
}

Resolution

The resolution is to stop the SMS Task Sequence Agent service on the client machine by killing the ‘tsmanager.exe‘ process. You can then push-install the client again from the SCCM Console, or you can trigger it manually from the client itself using process described below.

Kill the tsmanager Process Remotely

The following Powershell script will detect if the tsmanager process is running and kill it if it is. Enter the computername in the variable.

<#
Ths script checks whether the 'Task Sequence Manager' process is running on a client machine and kills it if it is.
For troubleshooting SCCM client upgrade issues.
#>

$ComputerName = "DB-MyLaptop"

# Test connectivity to the computer
if (Test-Connection -Quiet -Count 2 -ComputerName $ComputerName -ErrorAction SilentlyContinue)
{$Online = "Yes"}else{$Online = "No"}
if ($Online -eq "No")
{write-host "$ComputerName is not online!"}
if ($Online -eq "Yes")
{
# Start Remote Registry Service to allow Get-Process to run
(Get-Service -ComputerName $ComputerName -Name RemoteRegistry).Start()

# Check if tsmanager is running
if (Get-Process tsmanager -ComputerName $ComputerName)
{$tsmanager = "Yes"}else{$tsmanager = "No"}

# if yes, kill it...
If ($tsmanager -eq "Yes")
{
Write-Host "tsmanager process exists"
Write-Host "killing process..."
Invoke-Command -computername $ComputerName {Stop-Process -processname "TSManager" -Force}
}

# if no...
if ($tsmanager -eq "No")
{
Write-Host "tsmanager process does not exist"
}

# Stop Remote Registry Service
(Get-Service -ComputerName $ComputerName -Name RemoteRegistry).Stop()
}

Delete the ccmsetup Service Remotely

Once you have killed the tsmanager process, it is possible to manually trigger the installation of the SCCM client remotely using Powershell. This uses the ccmsetup.exe file that has already been copied to the machine. But first you must kill any existing ccmsetup process and service. This script will do that. Enter the computername in the variable.


<#
Ths script checks whether the 'ccmsetup' service is present on a client machine and deletes it if it is.
#>
$ComputerName = "DB-MyLaptop"

# Test connectivity to the computer
if (Test-Connection -Quiet -Count 2 -ComputerName $ComputerName -ErrorAction SilentlyContinue)
{$Online = "Yes"}else{$Online = "No"}
if ($Online -eq "No")
{write-host "$ComputerName is not online!"}
if ($Online -eq "Yes")
{
# Start Remote Registry Service to allow Get-Process to run
(Get-Service -ComputerName $ComputerName -Name RemoteRegistry).Start()

# Check if ccmsetup is running
if (Get-Service ccmsetup -ComputerName $ComputerName -ErrorAction SilentlyContinue)
{$ccmsetup = "Yes"}else{$ccmsetup = "No"}

# if yes...
If ($ccmsetup -eq "Yes")
{
Write-Host "ccmsetup service exists"
$Status = (Get-Service -ComputerName $ComputerName -Name ccmsetup -ErrorAction SilentlyContinue).Status
write-host "ccmsetup service is $status"
if ($Status = "Stopped")
{
write-host "Deleting service..."
$service = Get-WmiObject -ComputerName $ComputerName -Class Win32_Service -Filter "Name='ccmsetup'"
$service.delete() | Out-Null
(Get-Service ccmsetup -ComputerName $ComputerName -ErrorAction SilentlyContinue)
}
}

# if no...
if ($ccmsetup -eq "No")
{
Write-Host "ccmsetup service does not exist"
}

# Stop Remote Registry Service
(Get-Service -ComputerName $ComputerName -Name RemoteRegistry).Stop()
}

Trigger the Client Installation Again

This script will trigger the installation of the SCCM client from the ccmsetup.exe already copied to the machine by a previous push-installation attempt. Enter the computername in the variable, and the SMS Site Code at the relevant place.


<#
Ths script remotely triggers an SCCM client upgrade installation from files already cached on the machine.
Requires Powershell remoting
#>
$ComputerName = "DB-MyLaptop"
# Test connectivity to the computer
if (Test-Connection -Quiet -Count 2 -ComputerName $ComputerName -ErrorAction SilentlyContinue)
{$Online = "Yes"}else{$Online = "No"}
if ($Online -eq "No")
{write-host "$ComputerName is not online!"}
if ($Online -eq "Yes")
{
$s = New-PSSession -ComputerName $ComputerName

Write-Host "Starting SCCM Client installation on $Computername"
# Main script
Invoke-Command -Session $s -ScriptBlock `
{
Start-Process -FilePath "C:\windows\ccmsetup\ccmsetup.exe" -ArgumentList "SMSSITECODE=PS1" -Verbose
}
Remove-PSSession $s
}

In my environment, I included these activities in the Client Checks script we ran previously, so if this error was detected, it would be automatically remedied.  This makes troubleshooting a lot easier!

Next time, we’ll look at WMI issues.

Troubleshooting ConfigMgr 2012 Client Migration using Powershell (Part 3)

In this post, we’ll start looking at some of the common reasons why client upgrades fail, and how to resolve them.

Firewall Restrictions or Missing Boundaries

If the client computer has the Windows firewall turned on and the required exceptions are not made, then it may report in the CCM.log on the site server that it couldn’t connect to that machine.  The windows firewall requirements are documented here: http://technet.microsoft.com/en-us/library/gg682180.aspx.

If the client machine is behind a firewall that does not allow access to the SCCM server or the local distribution point, then it will be unable to get the files it needs to install the client. For example, on one remote site, access was restricted by the firewall to certain servers only, and the SCCM servers were not included. The SCCM server was able to copy the ccmsetup.exe to the client machine and start it, but it was then unable to get the files it needed from the local DP to install the client. This resulted in the following error in the ccmsetup.log on the client:

Failed to send HTTP request. (Error at WinHttpSendRequest: 12002)

In addition, if the client is not a member of an SCCM boundary, and no fallback location is permitted in the ConfgMgr client package, the client will not be able to get the files it needs to install the SCCM client.  Nickolaj Andersen has a nice post to identify if an IP is within a boundary: http://www.scconfigmgr.com/2014/04/15/check-if-an-ip-address-is-within-an-ip-range-boundary-in-configmgr-2012/

Machine is not Online, or Doesn’t Exist

In many cases, the reason the ConfigMgr client did not upgrade is simply because the client machine is not currently online.  ConfigMgr will try every hour for 7 days to push the client again.  If it hasn’t succeeded in this time period, it will give up, therefore if the client has not been succesfully installed or the problem remediated during this time period, you will need to push the client installation again from the ConfigMgr console. You can push it to the entire collection that contains computers without the SCCM 2012 client, if desired.

If the computer is not online, or doesn’t in fact exist, you will see errors like this in the CCM.log:

—> Attempting to connect to administrative share ‘\DB-MyLaptop\admin$’ using account ‘mydomain\sccmadmin’

—> WNetAddConnection2 failed (LOGON32_LOGON_NEW_CREDENTIALS) using account mydomain\sccmadmin (00000035)

—> The device DB-MyLaptop does not exist on the network. Giving up

—> ERROR: Unable to access target machine for request: “2097156880”, machine name: “DB-MyLaptop”, access denied or invalid network path.

In some cases, there are stale computer accounts in Active Directory, for example the machine was rebuilt with a different name, and was not first removed from the domain.  There may also be stale computer records in ConfigMgr, depending on the defined period of the maintenance tasks that clear out old records.  In these cases, the client records should be removed from AD/ConfigMgr.

DNS Errors

If the client is not properly registered in DNS, ConfigMgr may report that it cannot connect to the machine in the CCM.log. For example, I had one such case where I could ping the machine and I could connect to the admin$ share by it’s IP address, but not by it’s hostname. After searching in DNS I found multiple A records for different hostnames associated with the IP address! So after deleting the additional A records and flushing the DNS on the SCCM site server, the client push install went through successfully.

Unsupported Operating System

The client machine must be at Windows XP SP3 or above for the 2012 client installation to work, otherwise it will report it as an unsupported OS in the CCM.log:

—> OS is X86 bit Windows XP, Service Pack less than 3, returning as this is an unsupported OS

ERROR: Target machine (DB-MyLaptop) must be Windows 2003 SP2 or Windows XP SP3 or newer
Install SP3 or upgrade the machine to a newer OS to install the 2012 client.

Incorrect RPC Port Range Assignment

Symptoms

This problem took a long time to track down the cause! The symptoms are you cannot access the WMI on the machine, and the following error is reported in the CCM.log:

  • —> Unable to connect to WMI on remote machine “”DB-MyLaptop””, error = 0x80070057.

This error code means ‘The parameter is incorrect’.  When you run wbemtest utility and try to remotely connect to the WMI on that machine, you get the same error.

Also, the ‘Connection-oriented TCP/IP’ protocol is set to use ‘Intranet Range’ when you view the DCOM properties of the machine:

  • Run DCOMCNFG on the machine
  • Under Component Service, go to Computers > My Computer
  • Right-click My Computer and choose Properties
  • On the ‘Default Protocols’ tab, choose ‘Connection-oriented TCP/IP’ and click Properties
  • By default, it should look like the screenshot below. If it is using the ‘Intranet range’ and no port ranges are assigned, then you probably have this problem.

dcom

 Cause

Actually, there was nothing much wrong with the WMI on that machine, and the problem wasn’t with WMI, neither in the DCOM security, which was all set correctly. It turns out that the DCOM ‘Connection-oriented TCP/IP’ protocol was set in the registry to use InternetPorts, yet no ports were defined, therefore no connections were being allowed.

In the following registry key, there is no subkey called ‘Internet’ by default:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Rpc

It has to be created manually, and this can be done to allow RPC communication on pre-defined ports, as described in the Microsoft KB: http://support.microsoft.com/kb/154596. This is usually done for security reasons. But if the keys are not created correctly, for example you create the ‘UseInternetPorts‘ key, but don’t create the corresponding keys to define which ports are to be used, then RPC communication to that machine will fail.

Resolution

In the case that you are not intentionally using pre-defined RPC ports, then simply delete the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Rpc\Internet and all it’s subkeys, then reboot the computer, and RPC access will be restored.

You can use this Powershell script to delete the registry key on a remote computer. It will also get the logged on user, so you can ask them to reboot their machine.  It must be run as administrator, and with an account that has local admin rights on the remote computer.

$Path = "HKLM:\SOFTWARE\Microsoft\Rpc\Internet"
$ComputerName = "DB-MyLaptop"

$s = New-PSSession -ComputerName $ComputerName
Invoke-Command -Session $s -Argu $Path,$ComputerName -ScriptBlock `
{
param ($Path,$ComputerName)

if (Test-Path $Path)
{
write-host "$Path exists in the registry on $ComputerName. Attempting deletion of key..."
Remove-Item $Path -Recurse -Force
if (Test-Path $Path)
{
write-host "$Path could not be deleted!"
}
else
{
write-host "$Path was deleted!"
}
}
else
{
write-host "$Path does not exist in registry on $ComputerName"
}
}
Remove-PSSession $s

# Get logged on user
Write-host "Logged on user:"
@(Get-WmiObject -ComputerName $ComputerName -Namespace root\cimv2 -Class Win32_ComputerSystem)[0].UserName

Next time we’ll look at another cause of ConfigMgr client upgrade failure.

Troubleshooting ConfigMgr 2012 Client Migration using Powershell (Part 2)

In this post, we’ll run a Powershell script that will perform the client checks we discussed in the last post, against multiple machines that failed to install the ConfigMgr client.  Note, all the scripts in these posts are designed to run in Powershell ISE.

Create a Collection for Computers without the SCCM Client

The first thing we need to do is to put all the machines that don’t have the SCCM 2012 client installed into one collection, so we can work with them all at once.

  • In the SCCM Console, navigate to Assets and Compliance > Device Collections
  • Create a new collection, for example ‘All Computers with no SCCM client installed’
  • Give it a query-based rule, and use a query like the following to identify all workstations and servers for that site that have no SCCM 2012 client installed:
    • select SMS_R_SYSTEM.ResourceID,SMS_R_SYSTEM.ResourceType,SMS_R_SYSTEM.Name,SMS_R_SYSTEM.SMSUniqueIdentifier,SMS_R_SYSTEM.ResourceDomainORWorkgroup,SMS_R_SYSTEM.Client from SMS_R_System where (SMS_R_System.Client is null or SMS_R_System.Client = “0”) order by SMS_R_System.Name
  • View the members of the collection and you should see that they all have ‘Client Type’ = ‘None’ and ‘Client’ = ‘No’

Run the Powershell Script

Now that you have the collection, you can run the Powershell script below against that collection.

  • You must have local administrator rights to the client computers and you must have read-access to SCCM collections to run this script
  • Powershell remoting must be open on the ConfigMgr Site server.
  • Open the script in a Powershell ISE. It can be run on your local computer, it will contact the SCCM server remotely so it doesn’t need to be run there
  • In the ‘$Collection’ variable, change the name to the name of the collection you created earlier
  • Enter your Site server name and Site Code in the variables
  • Run the script and view the output in the ISE window

What Does the Script Do?

  1. First we connect to the ConfigMgr Site server will Powershell remoting and get the members of the collection we created earlier
  2. We export this into a csv file on the Site server, at C:\Scripts\Staging\ClientCSVs\computernames.csv (change the path as needed)
  3. We create some local directories to store stuff, then create a second csv file and put some headers in it
  4. Then we import the members of the first csv, and run checks against all those machines, adding the data to the second csv file.  We also copy client logs from the remote machines to the local machine where these are available, so they can be easily viewed from one place

Reviewing the Results

While the script is running it will inform you if a machine is offline, or if it cannot connect to the admin$ share. When the script has completed, it will open the directory containing the files it created, something like this:

report

The subfolders with the computer names contain the ccmsetup log files from the client machine. You can review these using the CMTrace utility to find any errors.

The report.csv contains the results of the checks against the client machine. Open it in Excel, and filter the ‘Machine is Online’ column to show only those machines that are online.

excel

These results, together with the client log files and the CCM.log on the site server, will help you identify where the problem is occurring with each client.

Since the ConfigMgr Client Push method will attempt to push the SSCM client to the machine every hour for 7 days, if the machine is still not online or the problem is not remediated with the 7 days, you will need to push the client again. This can be done to the entire collection at once using the SCCM Console.

In the next post, we’ll look at some common reasons for client upgrade/installation failure, and how to remediate them.

The Powershell Script

<#
This script performs inital client checks on a collection of remote hosts where the SCCM client failed to upgrade/install.
#>
$Collection = "All Computers with NO SCCM Client Installed"
$SiteServer = "PS1sccm-01"
$SiteCode = "PS1"

#####################################
# Get the members of the collection #
#####################################

cls
write-host "###########################################"
write-host "# ConfigMgr Client Upgrade Failure Script #"
Write-Host "###########################################"
Write-Host ""
write-host "Getting members of '$collection' collection"

$s = New-PSSession -ComputerName $SiteServer
Invoke-Command -Session $s -Argu $Collection -ScriptBlock `
{
param ($Collection)
Import-Module 'C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'
$Drive = $SiteCode + ':'
cd $Drive

$Computernames = @(Get-CMDevice -CollectionName $Collection | Select Name | Sort Name)
foreach ($ComputerName in $Computernames)
{$ComputerName = $ComputerName.Name
$ComputerName | out-file -filepath C:\Scripts\Staging\ClientCSVs\computernames.csv -Append
}
$Countremote = (Get-CMDevice -CollectionName $Collection | Select Name).Count
}
$countlocal = Invoke-Command -Session $s -ScriptBlock { $countremote }
Remove-PSSession $s
write-host "Collection contains $countlocal members"

################################################################
# Create local directories to store files, and create CSV file #
################################################################

# Create Directory for files if doesn't exist
if (Test-Path $env:USERPROFILE\ClientLogFiles)
{}
else
{
New-Item -Path "$env:USERPROFILE\ClientLogFiles" -ItemType Directory | Out-Null
}
New-Item -Path "$env:USERPROFILE\ClientLogFiles\$(Get-Date -Format yyyy-MM-dd-HH-mm)" -ItemType Directory | Out-Null
$location = "$env:USERPROFILE\ClientLogFiles\$(Get-Date -Format yyyy-MM-dd-HH-mm)"

# Create CSV file with headers
$headers = "Computer Name,Machine is online?,Can connect to admin$ share?,C:\Windows\CCM folder exists?,C:\Windows\ccmsetup exists?,C:\Windows\ccmsetup\scepinstall.exe,C:\Windows\ccmsetup\Logs exists?"
$headers | Out-File -FilePath $location\report.csv -Encoding UTF8

########################################
# Check each machine in the collection #
########################################

Write-Host 'Getting data for:'

$csv = Get-Content \\$SiteServer\c$\Scripts\Staging\ClientCSVs\computernames.csv

# Get data for each computer
Foreach ($ComputerName in $csv)
{
$online = $null,$admin = $null,$ccm = $null,$ccmsetup = $null,$scep = $null,$logs = $null
$ComputerName

# Test connectivity to the computer
if (Test-Connection -Quiet -Count 2 -ComputerName $ComputerName -ErrorAction SilentlyContinue)
{
$Online = "Yes"
}
else
{
$Online = "No"
Write-host " Offline" -ForegroundColor Gray
}

# Test admin$ path
if ($Online -ne "No")
{
if (Test-Path \\$ComputerName\admin$)
{
$admin = "Yes"
}
else
{
$admin = "No"
Write-host " Cannot connect to admin$ share" -ForegroundColor Red
}
}

# Test CCM folder
if ($admin -ne "No")
{
if (Test-Path \\$ComputerName\C$\Windows\CCM)
{
$ccm = "Yes"
}
else
{
$ccm = "No"
}

# Test ccmsetup folder
if (Test-Path \\$ComputerName\C$\Windows\ccmsetup)
{
$ccmsetup = "Yes"
}
else
{
$ccmsetup = "No"
}

# Test if scepinstall.exe is present
if ($ccmsetup -ne "No")
{
if (Test-Path \\$ComputerName\C$\Windows\ccmsetup\scepinstall.exe)
{
$scep = "Yes"
}
else
{
$scep = "No"
}

# Copy ccmsetup logs
if (Test-path \\$ComputerName\C$\Windows\ccmsetup\Logs)
{
$logs = "Yes"
}
else
{
$logs = "No"
}
if ($logs -eq "Yes")
{
Copy-Item \\$ComputerName\C$\Windows\ccmsetup\Logs $location\$ComputerName\Logs -Recurse
}
}
}

###########################
# Output data to CSV file #
###########################

$list = "$ComputerName,$online,$admin,$ccm,$ccmsetup,$scep,$logs"
$list | Out-File -FilePath $location\report.csv -Encoding UTF8 -Append
$online = $null,$admin = $null,$ccm = $null,$ccmsetup = $null,$scep = $null,$logs = $null
}
# Delete temp csv
Remove-Item \\$SiteServer\c$\Scripts\Staging\ClientCSVs\computernames.csv

# Open the directory
Invoke-Item $location