Using PowerShell for automated UNIX/Linux Agent Discovery
December 6, 2012 8 Comments
PowerShell cmdlets for administration of UNIX/Linux agents were added in the System Center 2012 release of Operations Manager. There is good documentation available on the cmdlet use, but a basic discovery script might look something like this:
$SSHCredential=Get-SCXSSHCredential
$WSCredential=Get-Credential
$Pool = Get-SCOMResourcePool -DisplayName “All Management Servers Resource Pool”
$DiscResult = Invoke-SCXDiscovery -name $HostName -ResourcePool $Pool -WsManCredential $WSCredential -SshCredential $SSHcredential
$DiscResult | Install-scxagent
In this example, the Invoke-SCXDiscovery cmdlet is provided the following parameters:
- $Hostname – the fqdn of the agent to discover
- $Pool – the Resource Pool object used to discover and manage the agent, from Get-SCOMResourcePool
- $WSCredential – a PSCredential object used for WSMan authentication, from Get-Credential
- $SSHCredential – an ssh Credential object used for ssh authentication, from Get-SCXSSHCredential
If you have tried a PowerShell discovery like this, you’ll know that both Get-Credential and Get-SCXSSHCredential prompt you for credential input and don’t allow specification of passwords as command-line arguments. This is for good reason, as plain-text scripts are a bad place to store passwords. However, this does have the effect of limiting your ability to truly automate UNIX/Linux agent discovery. Well, with a bit of extra scripting, you can actually embed your credentials in a script in a fairly secure manner.
This article does a great job explaining how to securely write a password to a file, and then retrieve it from a script. The steps to do this are:
- Logged in as the user that will run the script, create a credential object with: $Credential = Get-Credential
- Write this as a secure string to a file:
$credential.Password | ConvertFrom-SecureString | Set-Content $env:userprofile\password.txt
Now, this password can be read back into a script (but only if the script is run with the same user that wrote the password to the file), by using the following scriptlet:
$wsmanuser=”monuser”
$wsmanpassword = Get-Content $env:userprofile\password.txt | ConvertTo-SecureString
$WSCredential = New-Object System.Management.Automation.PSCredential ($wsmanuser, $wsmanpassword)
Using this method, we can securely create the credential object to use as our WSManCredential value without a prompt, but Invoke-SCXDiscovery also needs an ssh Credential. The ssh Credential is a bit more involved, but can be done in a similar fashion.
A function to create the ssh Credential object, using encrypted passwords stored in files is:
function Get-SCXSSHCredentialFromScript{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$True)]
[string]$UserName,
[string]$PassphraseFile,
[string]$SSHKeyFile,
[string]$SuPasswordFile,
[string]$ElevationType
)process {
$SSHcredential=””
$scred=””
$SSHcredential = New-Object Microsoft.SystemCenter.CrossPlatform.
ClientLibrary.CredentialManagement.Core.CredentialSet
$scred = New-Object Microsoft.SystemCenter.CrossPlatform.
ClientLibrary.CredentialManagement.Core.PosixHostCredential
$scred.Usage = 2
$scred.PrincipalName = $usernameif ($PassphraseFile.Length -gt 0){
$sPassphrase=Get-Content $PassphraseFile | ConvertTo-SecureString
$scred.Passphrase = $sPassphrase
}if ($SSHKeyFile.Length -gt 0) {
$scred.KeyFile = $SSHKeyFile
Write-Host “Validating SSH Key”
$scred.ReadAndValidateSshKey()
}#add posixhost credential to credential set
$SSHcredential.Add($scred)if ($elevationType.Equals(“su”)) {
$sucred = New-Object Microsoft.SystemCenter.CrossPlatform.
ClientLibrary.CredentialManagement.Core.PosixHostCredential
$sucred.Usage = 32 #su elevation
$sucred.PrincipalName = “root”
$sucred.Passphrase = Get-Content $SUPasswordFile | ConvertTo-SecureString
$SSHcredential.Add($sucred)
}if ($elevationType.Equals(“sudo”)) {
$sudocred = New-Object Microsoft.SystemCenter.CrossPlatform.
ClientLibrary.CredentialManagement.Core.PosixHostCredential
$sudocred.Usage = 16 #su elevation
$SSHcredential.Add($sudocred)
}
Return $SSHCredential
}
}
With this function defined, it can be used like this:
PS C:\Users\Administrator> $SSHCredential=Get-SCXSSHCredentialFromScript -username:monuser -PassphraseFile:$env:userprofile\password.txt –ElevationType:sudo
PS C:\Users\Administrator> $SSHCredential
SshUserName : monuser
SshElevationType : sudo
Credentials : {, }
Count : 2
IsSSHKey : False
Usage : 0
Of course, this needs to be run in an OpsMgr shell, or the script needs to be prefaced with:
Import-Module “C:\Program Files\System Center 2012\Operations Manager\Powershell\OperationsManager\OperationsManager”
New-SCOMManagementGroupConnection localhost;
So, now we have snippets to create WSMan and ssh Credential objects, using an ecrypted password stored in a file. Building on this, we can define a function to invoke UNIX/Linux discovery and install the agent:
function DiscoverSCXAgents{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$True)]
[string]$Hostname
)
$PassphraseFile=”$env:userprofile\password.txt”
$SSHCredential=Get-SCXSSHCredentialFromScript -username:monuser -PassphraseFile:$PassphraseFile –ElevationType:sudo
$wsmanuser=”monuser”
$wsmanpassword = Get-Content $PassphraseFile | ConvertTo-SecureString
$WSCredential = New-Object System.Management.Automation.PSCredential ($wsmanuser, $wsmanpassword)
$Pool = Get-SCOMResourcePool -DisplayName “All Management Servers Resource Pool”
Write-Output “Attempting discovery of $Hostname”
$DiscResult = Invoke-SCXDiscovery -name $HostName -ResourcePool $Pool -WsManCredential $WSCredential -SshCredential $SSHcredential
$DiscResult | fl Succeeded, ErrorData
$DiscResult | Install-scxagent
}
Testing out the new function:
DiscoverSCXAgents “lnx-db-007.contoso.com”
Attempting discovery of lnx-db-007.contoso.com
Name AgentVersion ManagementPackPlatformIdentifier Id
—- ———— ——————————– —
lnx-db-007.c… 1.4.0-906 Microsoft.Linux.SLES.11 c5944ea1-e4f4-1908-ea15-d5be6ba7d14e
And with that, we can use an Orchestrator runbook to call our discovery script and fully automate UNIX/Linux agent discovery.