Tips for finding Knowledge Articles

  • - Enter just a few key words related to your question or problem
  • - Add Key words to refine your search as necessary
  • - Do not use punctuation
  • - Search is not case sensitive
  • - Avoid non-descriptive filler words like "how", "the", "what", etc.
  • - If you do not find what you are looking for the first time,reduce the number of key words you enter and try searching again.
  • - Minimum supported Internet Explorer version is IE9
Home  >
article

How to auto-enroll Windows servers into the cloud using Group Policies and RestAPI

11 April,19 at 11:50 AM

In the context of a demo for Forrester, I have been asked to explore the possibilty to automatically discover Windows systems and enrol them into the Cloud as resources managed by Centrify Privileges Service. The full request: "I would like to use Group Policy so when the Server startup it will register itself to the Cloud, can you help me?". After taking a moment to digest this, and being very familiar with both PowerShell and the RestAPI available with the Centrify Identity Platform, I answered "Yes of course! Let's do this".

 

I choose to wrap the RestAPI calls into a PowerShell script named cloud-self-register.ps1 that would be invoked using the startup script feature from a Computer Group Policy. This script is dropped onto the SYSVOL in my example, but as long as it's available on a read-for-everyone share you can put it wherever it suite you best.

 

Screen Shot 2016-05-09 at 09.53.01.png

 

Then I create a new Group Policy Object linked to an OU that contains Windows Servers in my Lab environment, this Group Policy use the PowerShell tab of the Scripts settings run at startup/login.

 

The GPO Settings, the full parameter line for this script being:

 

-Url oceanlab.my.centrify.com -Login resource-manager@oceanlab.my.centrify.com -Password  -Account @{"User"="Administrator";"Password"=""}


Screen Shot 2016-05-09 at 18.01.35.png

 

And the result

 

Screen Shot 2016-05-09 at 18.00.42.png

 

Before the Group Policy applied, I only had one Windows server enroled manually into the Cloud on my CPS Tenant, as well as a couple of Linux servers (just so you know, CPS stands for Centrify Privilege Service).

 

Screen Shot 2016-05-09 at 09.54.28.png

 

But once the Group Policy applied, and the server is restarted, then the PowerShell script do its magic and let the server auto-enrol

 

Screen Shot 2016-05-09 at 09.55.44.png

 

We can see that I have now a new Server enrolled, without me doing nothing else that let the Server restart.

 

Screen Shot 2016-05-09 at 09.57.35.png

 

This is of course particularly helpful to let your servers enrol themselves without having to bother doing them one by one (afterall a good Admin is a lazy Admin). But also it helps not missing any of these new servers built on a high volume in these days of heavy virtualisation.

 

Ok... so you didn't read this article just to see me talking about GPO. You want to see the magic in the script. And maybe try it yourself as you may not believe it to be so simple.

 

Below an unpolished script doing the magic. These kind of functions will be soon turn into proper Cmdlets, but that's a very good example of what you can achieve already with the Centrify RestAPI and some help from the Professional Services team. 

################################################
# Centrify Cloud Self Registering sample script
# Created by Fabrice Viguier from sample work by Nick Gamb
#
# Author : Fabrice Viguier
# Version: 1.1.302   First release
#          1.2.305   Adding abiltity to register an Account right after self-registering
################################################

param
(
[Parameter(Mandatory = $true, HelpMessage = "Specify the URL to use for the connction (by default cloud.centrify.com).")]
[System.String]$Url,

[Parameter(Mandatory = $false, HelpMessage = "Specify the Login name to use for the connection (User context will be used if not specified).")]
[System.String]$Login,

[Parameter(Mandatory = $false, HelpMessage = "Specify the Password to use for the connection (User will be prompted if not specified [RECOMMENDED]).")]
[System.String]$Password,

[Parameter(Mandatory = $false, HelpMessage = "Specify an Account to add to the Computer. Format has to be a Hash table: e.g. @{`"User`"=`"Administrator`", `"Password`"=`"Passw0rd`"}")]
[System.Object]$Account
)

# Debug preference
if ($PSCmdlet.MyInvocation.BoundParameters["Debug"].IsPresent) 
{
# Debug continue without waiting for confirmation
$DebugPreference = "Continue"
}
else 
{
# Debug message are turned off
$DebugPreference = "SilentlyContinue"
}

try
{
# Setup variable for connection
$Uri = ("https://{0}/Security/Login" -f $Url)
$ContentType = "application/json" 
$Header = @{ "X-CENTRIFY-NATIVE-CLIENT" = "1" }
Write-Host ("Connecting to Centrify Cloud Platform (https://{0})" -f $Url)

# Validating Login
if ([System.String]::IsNullOrEmpty($Login))
{
# Get User from context
$UserName = [System.Environment]::UserName
$DomainName = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
$Login = ("{0}@{1}" -f $UserName, $DomainName)
}

# Validating Password
if ([System.String]::IsNullOrEmpty($Password))
{
# Prompt User for password
Write-Host ("Login: {0}" -f $Login)
$PasswordString = Read-Host ("Password" -f $Login) -AsSecureString
$Password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($PasswordString))
}

# Debug informations
Write-Debug "--- CLOUD LOGIN ---"
Write-Debug ("Uri= {0}" -f $Uri)
Write-Debug ("ContentType= {0}" -f $ContentType)
Write-Debug ("Login= {0}" -f $Login)
Write-Debug ("Password= {0}" -f "******")# Password is masked in Debug

# Format Json query
$Json = ("{{`"user`":`"{0}`", `"password`":`"{1}`"`}}" -f $Login, $Password)

# Connect using RestAPI
$WebResponse = Invoke-WebRequest -Method Post -SessionVariable CipSession -Uri $Uri -Body $Json -ContentType $ContentType -Headers $Header -UseBasicParsing
$WebResponseResult = $WebResponse.Content | ConvertFrom-Json
if ($WebResponseResult.Success)
{
$PodFqdn = $WebResponseResult.Result.PodFqdn
# Validate that a valid .ASPXAUTH cookie has been returned for the CipConnection
$CookieUri = ("https://{0}" -f $PodFqdn)
$ASPXAuth = $CipSession.Cookies.GetCookies($CookieUri) | Where-Object { $_.Name -eq ".ASPXAUTH" }

if ([System.String]::IsNullOrEmpty($ASPXAuth))
{
# .ASPXAuth cookie value is empty
Throw ("Failed to get a .ASPXAuth cookie for Url {0}. Verify Url and try again." -f $CookieUri)
}
else
{
# Get FQDN for the current Computer
$FQDN = [System.Net.Dns]::GetHostByName("").HostName

# Registering Computer to the Cloud
$Uri = ("https://{0}/ServerManage/AddResource" -f $PodFqdn)
$ContentType = "application/json" 
$Header = @{ "X-CENTRIFY-NATIVE-CLIENT" = "1"; }

# Debug informations
Write-Debug "--- REGISTERING TO THE CLOUD ---"
Write-Debug ("Uri= {0}" -f $Uri)
Write-Debug ("ContentType= {0}" -f $ContentType)

# Format Json query
$Json = ("{{`"Name`":`"{0}`",`"FQDN`":`"{0}`",`"ComputerClass`":`"Windows`",`"SessionType`":`"Rdp`",`"Description`":`"Computer auto-enrolled using RestAPI.`"}}" -f $FQDN) 

# Connect using RestAPI
$WebResponse = Invoke-WebRequest -Method Post -Uri $Uri -Body $Json -ContentType $ContentType -Headers $Header -WebSession $CipSession -UseBasicParsing
$WebResponseResult = $WebResponse.Content | ConvertFrom-Json
if ($WebResponseResult.Success)
{
Write-Host ("Computer {0} succefully Cloud registred." -f $FQDN)
# Get the GUID of the registered Computer
$ComputerID = $WebResponseResult.Result

# Add Accounts if required
if($Account -ne [Void]$null)
{
# Add an Account to the Computer
$Uri = ("https://{0}/ServerManage/AddAccount" -f $PodFqdn)
$ContentType = "application/json" 
$Header = @{ "X-CENTRIFY-NATIVE-CLIENT" = "1"; }

# Debug informations
Write-Debug "--- REGISTERING TO THE CLOUD ---"
Write-Debug ("Uri= {0}" -f $Uri)
Write-Debug ("ContentType= {0}" -f $ContentType)

# Format Json query
$Json = ("{{`"User`":`"{0}`",`"Password`":`"{1}`",`"IsManaged`":true,`"UseWheel`":false,`"Description`":`"`",`"Host`":`"{2}`"}}" -f $Account.User, $Account.Password, $ComputerID)

# Connect using RestAPI
$WebResponse = Invoke-WebRequest -Method Post -Uri $Uri -Body $Json -ContentType $ContentType -Headers $Header -WebSession $CipSession -UseBasicParsing
$WebResponseResult = $WebResponse.Content | ConvertFrom-Json
if ($WebResponseResult.Success)
{
Write-Host ("Managed Account {0} succefully added." -f $Account.User)
}
else
{
# Query error
Throw $WebResponseResult.Message
}
}
}
else
{
if ($WebResponseResult.Message -match "Resource already exists")
{
Write-Warning ("Computer {0} is already Cloud registred. Skipping registration." -f $FQDN)
}
else
{
# Query error
Throw $WebResponseResult.Message
}
}
}
}
else
{
Throw $CisLogin.Message
}
}
catch
{
Throw $_.Exception   
}

 

Still have questions? Click here to log a technical support case, or collaborate with your peers in Centrify's Online Community.

Related Articles

No related Articles