Skip to content

Instantly share code, notes, and snippets.

@raandree
Last active July 15, 2020 08:30
Show Gist options
  • Save raandree/f75ebdc585013017fd3f1a5d900e0210 to your computer and use it in GitHub Desktop.
Save raandree/f75ebdc585013017fd3f1a5d900e0210 to your computer and use it in GitHub Desktop.
JEA: Register a new restricted endpoint with JEA roles
function Unlock-AAAccount
{
param(
[Parameter(Mandatory)]
[string]$Identity
)
try
{
$user = Get-ADUser -Identity $Identity
}
catch
{
Write-Error "The user '$Identity' does not exist"
return
}
if (-not $user.LockedOut)
{
Write-Error "The user '$Identity' is not locked out"
return
}
try
{
$user | Unlock-ADAccount
$message = "User '$Identity' has been unlocked"
}
catch
{
$message = "Failed to unlock user '$Identity'"
}
$logName = '{0:yyMMdd}ActivityLog.txt' -f (Get-Date)
Write-Host $message
'{0:yyMMdd HH:mm:ss} {1,20} {2} | {3}' -f (Get-Date), $MyInvocation.MyCommand.Name, $PSSenderInfo.ConnectedUser, $message |
Out-File C:\PowerShellTranscripts\$jeaModuleName\$logName -Append
}
function Reset-AAPassword
{
param(
[Parameter(Mandatory)]
[string]$Identity
)
try
{
$user = Get-ADUser -Identity $Identity
}
catch
{
Write-Error "The user '$Identity' does not exist"
return
}
Add-Type -AssemblyName System.Web
$password = [System.Web.Security.Membership]::GeneratePassword(10,4)
$securePassword = $password | ConvertTo-SecureString -AsPlainText -Force
$user | Set-ADAccountPassword -NewPassword $securePassword
$user | Set-ADUser -ChangePasswordAtLogon $true
$message = "Password for user '$Identity' has been changed to '$password'. Password must be changed at next logon."
$logName = '{0:yyMMdd}ActivityLog.txt' -f (Get-Date)
Write-Host $message
'{0:yyMMdd HH:mm:ss} {1,20} {2} | {3}' -f (Get-Date), $MyInvocation.MyCommand.Name, $PSSenderInfo.ConnectedUser, $message |
Out-File C:\PowerShellTranscripts\$jeaModuleName\$logName -Append
}
function Add-AADnsServerRecordA
{
param(
[Parameter(Mandatory)]
[string]$Name,
[Parameter(Mandatory)]
[ipaddress]$IpAddress,
[Parameter(Mandatory)]
[string]$ZoneName
)
$dnsZone = Get-DnsServerZone -Name $ZoneName -ErrorAction SilentlyContinue
if (-not $dnsZone)
{
Write-Error "DNS Zone '$ZoneName' does not exist"
return
}
$dnsRecord = Get-DnsServerResourceRecord -Name $Name -ZoneName $ZoneName -RRType A -ErrorAction SilentlyContinue
if ($dnsRecord)
{
Write-Error "The DNS A record '$Name' does already exist in zone '$ZoneName'"
return
}
Add-DnsServerResourceRecordA -Name $Name -ZoneName $ZoneName -IPv4Address $IpAddress
$message = "DNS A record '$Name' created in zone '$ZoneName'"
$logName = '{0:yyMMdd}ActivityLog.txt' -f (Get-Date)
Write-Host $message
'{0:yyMMdd HH:mm:ss} {1,20} {2} | {3}' -f (Get-Date), $MyInvocation.MyCommand.Name, $PSSenderInfo.ConnectedUser, $message |
Out-File C:\PowerShellTranscripts\$jeaModuleName\$logName -Append
}
function Get-AAUser
{
param(
[Parameter(Mandatory)]
[string]$Identity
)
try
{
$user = Get-ADUser -Identity $Identity -Properties *
}
catch
{
Write-Error "The user '$Identity' does not exist"
return
}
$user
}
function UserManagement
{
$roleName = $MyInvocation.MyCommand.Name
New-PSRoleCapabilityFile -Path C:\$roleName.psrc `
-ModulesToImport Microsoft.PowerShell.Management, ActiveDirectory `
-VisibleProviders FileSystem `
-VisibleCmdlets Get-Command, Get-Help `
-FunctionDefinitions `
@{ Name = 'Unlock-AAAccount'; ScriptBlock = (Get-Command Unlock-AAAccount).ScriptBlock },
@{ Name = 'Reset-AAPassword'; ScriptBlock = (Get-Command Reset-AAPassword).ScriptBlock }
# Create the RoleCapabilities folder and copy in the PSRC file
$modulePath = Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell\Modules\$jeaModuleName"
$rcFolder = Join-Path -Path $modulePath -ChildPath "RoleCapabilities"
if (-not (Test-Path -Path $rcFolder))
{
mkdir -Path $rcFolder -Force | Out-Null
}
Copy-Item -Path C:\$roleName.psrc -Destination $rcFolder
}
function UserInfo
{
$roleName = $MyInvocation.MyCommand.Name
New-PSRoleCapabilityFile -Path C:\$roleName.psrc `
-ModulesToImport Microsoft.PowerShell.Management, ActiveDirectory `
-VisibleProviders FileSystem `
-VisibleCmdlets Get-Command, Get-Help `
-FunctionDefinitions `
@{ Name = 'Get-AAUser'; ScriptBlock = (Get-Command Get-AAUser).ScriptBlock }
# Create the RoleCapabilities folder and copy in the PSRC file
$modulePath = Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell\Modules\$jeaModuleName"
$rcFolder = Join-Path -Path $modulePath -ChildPath "RoleCapabilities"
if (-not (Test-Path -Path $rcFolder))
{
mkdir -Path $rcFolder -Force | Out-Null
}
Copy-Item -Path C:\$roleName.psrc -Destination $rcFolder
}
function DnsManagement
{
$roleName = $MyInvocation.MyCommand.Name
New-PSRoleCapabilityFile -Path C:\$roleName.psrc `
-ModulesToImport Microsoft.PowerShell.Management, DnsServer `
-VisibleProviders FileSystem `
-VisibleCmdlets Get-Command, Get-Help `
-FunctionDefinitions `
@{ Name = 'Add-AADnsServerRecordA'; ScriptBlock = (Get-Command Add-AADnsServerRecordA).ScriptBlock }
# Create the RoleCapabilities folder and copy in the PSRC file
$modulePath = Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell\Modules\$jeaModuleName"
$rcFolder = Join-Path -Path $modulePath -ChildPath "RoleCapabilities"
if (-not (Test-Path -Path $rcFolder))
{
mkdir -Path $rcFolder -Force | Out-Null
}
Copy-Item -Path C:\$roleName.psrc -Destination $rcFolder
}
function Register-CustomPSSessionConfiguration
{
param(
[string[]]$AllowedPrincipals,
[Parameter(Mandatory)]
[string]$EndpointName
)
if (-not (Test-Path -Path C:\PowerShellTranscripts))
{
mkdir -Path C:\PowerShellTranscripts | Out-Null
}
New-PSSessionConfigurationFile -Path c:\$EndpointName.pssc `
-SessionType RestrictedRemoteServer `
-LanguageMode RestrictedLanguage `
-RunAsVirtualAccount `
-ExecutionPolicy Unrestricted `
-TranscriptDirectory "C:\PowerShellTranscripts\$EndpointName" `
-RoleDefinitions @{
"$($env:USERDOMAIN)\UserManagement" = @{ RoleCapabilities = 'UserManagement', 'UserInfo' }
"$($env:USERDOMAIN)\DnsManagement" = @{ RoleCapabilities = 'UserInfo', 'DnsManagement' }
}
Register-PSSessionConfiguration -Name $EndpointName -Path C:\$EndpointName.pssc -Force
$pssc = Get-PSSessionConfiguration -Name $EndpointName
$psscSd = New-Object System.Security.AccessControl.CommonSecurityDescriptor($false, $false, $pssc.SecurityDescriptorSddl)
foreach ($allowedPrincipal in $AllowedPrincipals)
{
$account = New-Object System.Security.Principal.NTAccount($allowedPrincipal)
$accessType = "Allow"
$accessMask = 268435456
$inheritanceFlags = "None"
$propagationFlags = "None"
$psscSd.DiscretionaryAcl.AddAccess($accessType,$account.Translate([System.Security.Principal.SecurityIdentifier]),$accessMask,$inheritanceFlags,$propagationFlags)
}
Set-PSSessionConfiguration -Name $EndpointName -SecurityDescriptorSddl $psscSd.GetSddlForm("All") -Force
# Create a folder for the module
$modulePath = Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell\Modules\$jeaModuleName"
if (-not (Test-Path -Path $modulePath))
{
mkdir -Path $modulePath | Out-Null
}
# Create an empty script module and module manifest. At least one file in the module folder must have the same name as the folder itself.
$path = Join-Path -Path $modulePath -ChildPath "$jeaModuleName.psm1"
if (-not (Test-Path -Path $path))
{
New-Item -ItemType File -Path $path | Out-Null
}
$path = Join-Path -Path $modulePath -ChildPath "$jeaModuleName.psd1"
if (-not (Test-Path -Path $path))
{
New-ModuleManifest -Path $path -RootModule "$jeaModuleName.psm1"
}
}
Install-WindowsFeature -Name RSAT-Role-Tools, RSAT-DNS-Server
$password = 'Somepass1' | ConvertTo-SecureString -AsPlainText -Force
$jeaModuleName = 'Support'
$endpointName = 'Support'
$modulePath = Join-Path -Path $env:ProgramFiles -ChildPath "WindowsPowerShell\Modules\$jeaModuleName"
Remove-Item -Path $modulePath -Recurse -Force -ErrorAction SilentlyContinue
UserManagement
UserInfo
DnsManagement
$ou = New-ADOrganizationalUnit -Name JeaTest -ProtectedFromAccidentalDeletion $false -PassThru
$dnsManagementRoleGroup = New-ADGroup -Name DnsManagement -GroupScope Global -Path $ou -PassThru
$userManagementRoleGroup = New-ADGroup -Name UserManagement -GroupScope Global -Path $ou -PassThru
$dnsManager = New-ADUser -Name Bob -AccountPassword $password -Enabled $true -Path $ou -PassThru
$userManager = New-ADUser -Name Sue -AccountPassword $password -Enabled $true -Path $ou -PassThru
$dnsManagementRoleGroup | Add-ADGroupMember -Members $dnsManager
$userManagementRoleGroup | Add-ADGroupMember -Members $userManager
Register-CustomPSSessionConfiguration -EndpointName $endpointName -AllowedPrincipals "$($env:USERDOMAIN)\Domain Users"
return
Get-PSSessionCapability -ConfigurationName Support -Username Sue
Get-PSSessionCapability -ConfigurationName Support -Username Bob
#http://weiler.16mb.com/2016/10/17/jea-just-enough-administration-part-2/
#https://sid-500.com/2018/02/11/powershell-implementing-just-enough-administration-jea-step-by-step/
#https://blogs.technet.microsoft.com/datacentersecurity/2017/03/07/step-by-step-creating-a-jea-endpoint-for-dns-management/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment