We are currently in the process of migrating our all of the servers from one domain to our 'main' domain and as part of this project we are migrating the servers from their current SCOM environment to ours. This is normally very simple to be done through the SCOM Management Console; however, I have found that about 25% of the servers that I have been migrating are failing either during the uninstall, or the installation of the new client.
The failures are due to a number of things, because of permission issues, or ports not being opened, or just because the server doesn't feel like cooperating. Either way in order to make my work easier I created two functions to remotely install and uninstall the agent using Invoke-command and msiexec.exe and would like to share this scripts.
<#
.SYNOPSIS
Install SCOM Agent in a remote computer using MSIExec
.DESCRIPTION
This function will Install the SCOM Agent on a remote
computer using msiexec.exe. The function will require that you provide the name
of the computer, and if different to modify the path where the SCOM Agent
folder is located.
.PARAMETER computerName
The computer where you wish to uninstall the SCOM Agent
from.
.PARAMETER agentPath
The script will use the MOMAgent.msi to install the
SCOM Agent, therefor we'll need to copy the file over to the server.
This is currently done by copying the folder where the
file is located. The folder will be copied to the C drive under the folder
name SCOMAgent and will clean it up after the
installation is completed.
You can hard code this parameter so that it will always
use a default location under the 'Begin' section.
.EXAMPLE
PS C:\> Install-SCOMAgentMsiExec -ComputerName
SERVERNAME
.EXAMPLE
PS C:\> Install-SCOMAgentMsiExec -ComputerName
SERVERNAME -agentPath C:\agentPath\Folder
* Note: This is the folder where it is located,
not the msi file itself.
.INPUTS
System.String, [System.String]
.OUTPUTS
System.String
#>
function
Install-SCOMAgentMsiExec
{
[CmdletBinding()]
param (
[Parameter(Position
= 0, Mandatory =
$true)]
[System.String]$computerName,
[Parameter(Position
= 0, Mandatory =
$false)]
[System.String]$agentPath
)
begin
{
if ($agentPath.Length -eq 0 -or $agentPath -eq
$null)
{
$msiPath = # Default path here
}
$serverAgentPath =
"\\$($computerName)\c$\SCOMAgent"
}
# endbegin
process
{
if (-not (Test-Connection -ComputerName
$computerName -Count
1 -Quiet)) # Testing if Computer is online.
{
Write-Error -Message "$computerName cannot be pinged." -Category
ResourceUnavailable -ErrorAction Stop
}
else
{
Write-Verbose -Message
"$computerName is accepting pings."
}
# endelse
if (-not(Get-Service HealthService
-ComputerName $computerName
-ErrorAction SilentlyContinue))
# Ensure that the HealthService doesn't exists.
{
# Install the Agent if the service is not found.
Write-Verbose -Message
"The HealthService service is not installed.
Installing."
if (-not (Test-Path -Path $msiPath)) # Test
to ensure the Agent Path exists.
{
Write-Error -Message "Unable to find the location $msiPath."
-Category ObjectNotFound
-ErrorAction Stop
}
# endif
try
{
if (Test-Path -Path $serverAgentPath)
# Test if the destination folder exists.
{
Write-Verbose -Message
"The destination folder already exists. Ensure
no files are missing."
# If the Path exists, we'll compare the files to not
have to re-write data.
$sourceFiles =
Get-ChildItem $msiPath
$destinationFiles =
Get-ChildItem $serverAgentPath
if (-not (Compare-Object -ReferenceObject
$sourceFiles -DifferenceObject
$destinationFiles)) # Test if the folders are the same, and not missing
files.
{
# If the folders do not match delete the current
folder.
Write-Verbose -Message
"The folders do not match completely."
Remove-Item $serverAgentPath
-Recurse
# Copy the correct Agent data into the local folder.
Write-Verbose "Copying
files from $msiPath to $serverAgentPath"
Copy-Item $msiPath
-Destination $serverAgentPath
-Recurse -Force
}
# endif
else
{
Write-Verbose -Message
"The folders are identical. Proceeding."
}
# endelese
}
else
{
# If the folder doesn't exist copy the Agent data into the
local drive.
Write-Verbose "Copying
files from $msiPath to $serverAgentPath"
Copy-Item $msiPath
-Destination $serverAgentPath
-Recurse -Force
}
}
# endtry
catch
{
Write-Error -Message $Error[0].Exception -ErrorAction Stop
}
# endcatch
Write-Verbose -Message
"Uninstalling the SCOM Agent."
Invoke-Command -ComputerName
$computerName -ScriptBlock
{
Start-Process "C:\Windows\System32\msiexec.exe"
-ArgumentList "/i
C:\SCOMAgent\MOMAgent.msi /qn USE_SETTINGS_FROM_AD=0
USE_MANUALLY_SPECIFIED_SETTINGS=1 MANAGEMENT_GROUP=[GROUPNAME] MANAGEMENT_SERVER_DNS=[SERVERNAME] SECURE_PORT=[PORT] AcceptEndUserLicenseAgreement=1" -Wait
}
# We look in the computers eventlog to find the MsiExec
log for the installation in the last 5 minutes.
Write-Verbose -Message
"Confirming that the installation has been a
success."
$eventLog = Get-EventLog -ComputerName
$computerName -LogName
Application -InstanceId
11707 -Newest
1 -Message "Product: Microsoft Monitoring Agent -- Installation
operation completed successfully." -After
$((Get-Date).AddMinutes(-5))
if ($eventLog
-ne $null)
# Check if the EventLog was found.
{
Write-Verbose -Message
"The HealthService service has been
installed."
}
# endif
else
{
Write-Error -Message "The installation failed." -Category NotInstalled
-ErrorAction Stop
}
# endcatch
}
# endif
else
{
Write-Error -Message "The HealthService is already installed."
-Category InvalidOperation
-RecommendedAction "Uninstall
the agent before proceeding." -ErrorAction
Stop
}
# endelse
}
# endprocess
end
{
Write-Verbose -Message
"Removing the Agent folder."
Remove-Item $serverAgentPath
-Recurse
}
# endEnd
} #
endfunction
<#
.SYNOPSIS
Uninstall SCOM Agent in a remote computer using MSIExec
.DESCRIPTION
This function will Uninstall the SCOM Agent on a remote
computer using msiexec.exe. The function will require that you provide the
name of the computer, and if different to modify the
path where the SCOM Agent folder is located.
.PARAMETER computerName
The computer where you wish to uninstall the SCOM Agent
from.
.PARAMETER agentPath
The script will use the MOMAgent.msi to uninstall the
SCOM Agent, therefor we'll need to copy the file over to the server.
This is currently done by copying the folder where the
file is located. The folder will be copied to the C drive under the folder
name SCOMAgent and will clean it up after the uninstallation
is completed.
You can hard code this parameter so that it will always
use a default location under the 'Begin' section.
.EXAMPLE
PS C:\> Uninstall-SCOMAGentMsiExec -ComputerName
SERVERNAME
.EXAMPLE
PS C:\> Uninstall-SCOMAGentMsiExec -ComputerName
SERVERNAME -agentPath C:\agentPath\Folder
* Note: This is the folder where it is located,
not the msi file itself.
.INPUTS
System.String, [System.String]
.OUTPUTS
System.String
#>
function
Uninstall-SCOMAgentMsiExec
{
[CmdletBinding()]
param (
[Parameter(Position
= 0, Mandatory =
$true)]
[System.String]$computerName,
[Parameter(Position
= 0, Mandatory =
$false)]
[System.String]$agentPath
)
begin
{
if ($agentPath.Length -eq 0 -or $agentPath -eq
$null)
{
$msiPath = # Default path here
}
$serverAgentPath =
"\\$($computerName)\c$\SCOMAgent"
}
# endbegin
process
{
if (-not (Test-Connection -ComputerName
$computerName -Count
1 -Quiet)) # Testing if Computer is online.
{
Write-Error -Message "$computerName cannot be pinged." -Category
ResourceUnavailable -ErrorAction Stop
}
# endif
else
{
Write-Verbose -Message
"$computerName is accepting pings."
}
# endelse
if (Get-Service HealthService -ComputerName
$computerName -ErrorAction
Stop) #
Check if the HealthService exists.
{
Write-Verbose -Message
"The HealthService service is installed.
Proceeding with uninstallation."
if (-not (Test-Path -Path $msiPath)) # Test
to ensure the Agent Path exists.
{
Write-Error -Message "Unable to find the location $msiPath."
-Category ObjectNotFound
-ErrorAction Stop
}
# endif
try
{
if (Test-Path -Path $serverAgentPath)
# Test if the destination folder exists.
{
Write-Verbose -Message
"The destination folder already exists. Ensure
no files are missing."
# If the Path exists, we'll compare the files to not
have to re-write data.
$sourceFiles =
Get-ChildItem $msiPath
$destinationFiles =
Get-ChildItem $serverAgentPath
if (-not (Compare-Object -ReferenceObject
$sourceFiles -DifferenceObject
$destinationFiles)) # Test if the folders are the same, and not missing
files.
{
# If the folders do not match delete the current
folder.
Write-Verbose -Message
"The folders do not match completely."
Remove-Item $serverAgentPath
-Recurse
# Copy the correct Agent data into the local folder.
Write-Verbose "Copying
files from $msiPath to $serverAgentPath"
Copy-Item $msiPath
-Destination $serverAgentPath
-Recurse -Force
}
# endif
else
{
Write-Verbose -Message
"The folders are identical. Proceeding."
}
# endelese
}
else
{
#
If the folder doesn't exist copy the Agent data into the local drive.
Write-Verbose "Copying
files from $msiPath to $serverAgentPath"
Copy-Item $msiPath
-Destination $serverAgentPath
-Recurse -Force
}
}
# endtry
catch
{
Write-Error -Message $Error[0].Exception -ErrorAction Stop
}
# endcatch
Write-Verbose -Message
"Uninstalling the SCOM Agent."
Invoke-Command -ComputerName
$computerName -ScriptBlock
{ Start-Process "C:\Windows\System32\msiexec.exe"
-ArgumentList "/x
C:\SCOMAgent\MOMAgent.msi /qb" -Wait
}
# We look in the computers eventlog to find the MsiExec
log for the uninstallation in the last 5 minutes.
Write-Verbose -Message
"Confirming that the uninstallation has been a
success."
$eventLog = Get-EventLog -ComputerName
$computerName -LogName
Application -InstanceId
11724 -Newest
1 -Message "Product: Microsoft Monitoring Agent -- Removal
completed successfully." -After $((Get-Date).AddMinutes(-5))
if ($eventLog
-ne $null)
# Check if the EventLog was found.
{
Write-Verbose -Message
"The HealthService service has been
uninstalled."
}
# endif
else
{
Write-Error -Message "The uninstallation failed." -Category NotInstalled
-ErrorAction Stop
}
# endcatch
}
# endif
else
{
Write-Error -Message "The HealthService is not installed." -Category InvalidOperation
-ErrorAction Stop
}
# endelse
}
# endprocess
end
{
Write-Verbose -Message
"Removing the Agent folder."
Remove-Item $serverAgentPath
-Recurse
}
# endEnd
} #
endfunction
The main thing to notice here is that the script will need to have access to the location where the msi SCOM Installation file is located, and local administrator rights to the server.
The script will then copy the files to the local drive of the server and run the msi file. Once the installation runs it will check for a successful installation/uninstall eventlog and delete the data that it copied to the C drive.
I hope that this might help someone out there, and please let me know if you have any questions, feedback or concerns.
Kind regards,
Me.