Deploying JEA at Scale

At PowerShell Summit I did a session on Implementation JEA in your environment. Unfortunately to ran out of time and for one of the most important things. How do you deploy your JEA configuration to all your servers. I have had quite a few people ask me this via twitter so I though I would write it down for everyone.

If you missed PowerShell Summit here are the two JEA presentations that lead up to this. This article is part 3 of Deploying JEA. Below are part 1 by Jason Helmick and part 2 by James Petty.

Getting started with Just Enough Administration (JEA) by Jason Helmick

We decided to use a startup script configured by GPO’s to make sure the newest copy of our module is always there and that the current endpoints are registered.
First we need to make sure we have the most current version of your JEA Module on the server.

[powershell title=”Copy Your Jea Module”]
$RemoteModule = \\PATH_TO_YOUR_JEA_MODULE_HERE
$MachineModule = ‘C:\Program Files\WindowsPowerShell\Modules\MyJeaModule’

$moddest = ‘C:\Program Files\WindowsPowerShell\Modules’

if (-NOT (Test-Path $MachineModule)) {Copy-Item -Path $RemoteModule -Destination $moddest -Recurse -Force}

$RemoteModuleHash = Get-ChildItem $RemoteModule -Recurse | Get-FileHash | select @{Label="Path";Expression={$_.Path.Replace($RemoteModule,"")}},Hash
$MachineModuleHash = Get-ChildItem $MachineModule -Recurse | Get-FileHash | select @{Label="Path";Expression={$_.Path.Replace($MachineModule,"")}},Hash
$moddiffEM = ”

Compare-Object $RemoteModuleHash $MachineModuleHash -Property Path,Hash -IncludeEqual -PassThru | Where-Object {$_.SideIndicator -ne ‘==’ } |
ForEach-Object -process {
$moddiffEM = ‘y’
}

if ($moddiffEM) {
Copy-Item -Path $RemoteModule -Destination $moddest -Recurse -Force
}
[/powershell]

Next script we use is to make sure the correct endpoints are registered.

[powershell title=”Register Your EndPoints”]</pre>
$RemoteConfiguration = "Path_To_My_Jea_Configuration"
$LocalConfiguration = ‘C:\ProgramData\JEAConfiguration’

$JeaDestination = ‘C:\ProgramData’

if (-NOT (Test-Path $LocalConfiguration)) {
Copy-Item -Path $RemoteConfiguration -Destination $JeaDestination -Recurse -Force
Register-PSSessionConfiguration -Path "$LocalConfiguration\MyJeaConfiguration.pssc" -name EM -Force
}

if (-NOT (Test-Path $LocalConfiguration\*.pssc)) {
Copy-Item -Path $RemoteConfiguration -Destination $JeaDestination -Recurse -Force
Register-PSSessionConfiguration -Path "$LocalConfiguration\MyJeaConfiguration.pssc" -name EM -Force
}

$RemoteConfigurationHash = Get-ChildItem $RemoteConfiguration -Recurse | Get-FileHash | select @{Label="Path";Expression={$_.Path.Replace($RemoteConfiguration,"")}},Hash
$LocalConfigurationHash = Get-ChildItem $LocalConfiguration -Recurse | Get-FileHash | select @{Label="Path";Expression={$_.Path.Replace($LocalConfiguration,"")}},Hash
$jeadiffEM = ”

Compare-Object $RemoteConfigurationHash $LocalConfigurationHash -Property Path,Hash -IncludeEqual -PassThru | Where-Object {$_.SideIndicator -ne ‘==’ } |
ForEach-Object -process {
$jeadiffEM = ‘y’
}

if ($jeadiffEM) {
Copy-Item -Path $RemoteConfiguration -Destination $JeaDestination -Recurse -Force
Register-PSSessionConfiguration -Path "$LocalConfiguration\MyJeaConfiguration.pssc" -name EM -Force
}
<pre>[/powershell]

There will be a youtube recording of this blog in the very near future. I hope you enjoyed reading this article.

#NOTE
This article is written for informational purposes only. All code is provided as is and should be tested in your lab environment.