Hello,
Our scripting guy has finished his job. You need to complete several preparatory steps to make the script work.
Since there are no trust relationships between the domains, you cannot launch the script for all domains from the computer where your Adaxes service is installed. To launch a script in an untrusted domain, you need to launch it on a computer located in that untrusted domain with the help of PowerShell Remoting. For this purpose you need to configure a computer in each of the domains that will allow remote PowerShell sessions. The computer will be used to launch the script in that specific domain. Also, you need to install the Terminal Services PowerShell Module on each of such computers. These computers do not necessarily have to be servers, an ordinary workstation with PowerShell will be enough.
To configure a computer:
-
Install the Terminal Services PowerShell Module on the computer. You can download it here. You need the ZIP file, do not download the MSI package. To install the module, just unpack the contents of the ZIP file to %WINDIR%\System32\WindowsPowerShell\v1.0\Module, where %WINDIR% is the Windows directory.
-
Enable Remote PowerShell. To do this, you need to execute the Enable-PSRemoting -force command from the PowerShell console.
-
Also, you also need to configure PowerShell execution policy to disable blocking and prompts for execution of commands from the module. To do this, execute the Set-ExecutionPolicy Bypass -force command from the PowerShell console.
-
Make sure that the computer is trusted for delegation. To do this:
- Open Adaxes Administration Console.
- Expand the service node that represents your service.
- Navigate to the computer account you need and right-click it.
- Select Properties from the context menu.
- In the dialog box that appears, switch to the Delegation tab.
- Make sure that the radio button is switched to Trust this computer for delegation to any service.
Then, since there are no trust relationships between the domains, you need to add the computers that you've prepared to accept remote PowerShell sessions to trusted hosts on the computer where your Adaxes service is installed. To do this, execute the following command line on the computer where your Adaxes service is installed:
winrm s winrm/config/client '@{TrustedHosts="RemoteComputer1,RemoteComputer2"}'
where RemoteComputer1,RemoteComputer2 are Fully Qualified Domain Names (FQDNs) of the computers that you've configured to accept remote PowerShell sessions in each of your domains.
Now you have to prepare a CSV file with credentials required to connect to each of your domains. The first line should contain the following headers:
DomainName, ComputerName, UserName, Password
Then, you should specify credentials for each of your domains in the following format:
- 1st column - domain name,
- 2nd column - the name of the computer that you've configured to accept remote PowerShell sessions per the above instructions,
- 3rd column - user name of a user who has the Query Information, Logoff and Connect privileges for the computers located in that domain,
- 4th column - password for the account specified in the 3rd column.
There should be one line for each domain. Here's an example of such a file:
DomainName, ComputerName, UserName, Password
domain1.com,computer.domain1.com,Administrator@domain1.com,password
domain2.com,computer.domain2.com,administrator@domain2.com,password
Now, you need to import the credentials into a secure storage. To do this:
-
Copy the following script and save it to a file with the .ps1 exetnsion, say, Import-Credentinals.ps1.
Param($csvFilePath, [switch]$deleteOldCredentials) # Run the script with command line parameter -csvFilePath (CVS file path) and optional parameter -deleteOldCredentials
$scriptDirectoryPath = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)
# Create a directory for files with credentials
$credentialDirectoryPath = $scriptDirectoryPath + "\Credentials"
if ($deleteOldCredentials)
{
if ((Test-Path -Path $credentialDirectoryPath))
{
Get-Item -Path $credentialDirectoryPath | Remove-Item -Force -Recurse
}
}
if (!(Test-Path -Path $credentialDirectoryPath))
{
New-Item -ItemType directory -Path $credentialDirectoryPath | Out-Null
}
$credentialDirectory = Get-Item -Path $credentialDirectoryPath
# Import credentials from the CSV file
$domainsCSV = Import-Csv $csvFilePath
$fileCount = 0
foreach ($domainCSV in $domainsCSV)
{
$directoryPath = $credentialDirectory.FullName + "\" + $domainCSV.DomainName
if (!(Test-Path -Path $directoryPath))
{
New-Item -Type directory -Path $directoryPath | Out-Null
}
$directory = Get-Item -Path $directoryPath
$filePath = $directory.FullName + "\" + $domainCSV.ComputerName
if((Test-Path -Path $filePath))
{
Get-Item -Path $filePath | Remove-Item -Force -Recurse
}
$file = New-Item $filePath -Type file
Set-Content -Path $file.FullName -Value $domainCSV.UserName
ConvertTo-SecureString $domainCSV.Password -AsPlainText -Force | ConvertFrom-SecureString | Add-Content $file
$fileCount++
}
Write-Host "Import complete, $fileCount row(s) processed"
-
Open Windows Command Prompt (cmd.exe).
-
Run the saved script with the credentials of Adaxes default service administrator (the user that you specified during Adaxes installation) using the following command line:
RunAs /user:DOMAIN\DefaultServiceAdmin "PowerShell -file <full_script_file_path> -csvfilepath <full_csv_file_path> -deleteOldCredentials"
where
- DOMAIN\DefaultServiceAdmin - user name of Adaxes default service administrator,
- <full_script_file_path> - full path to the script that you saved on the 1st step,
- <full_csv_file_path> - full path to the CSV file with credentials,
- -deleteOldCredentials - an optional parameter that specifies whether to purge credentials from the secure storage before importing credentials from the CSV file. When this parameter is not specified, the script will just import the new credentials. If the CSV file contains credentials for a domain, credentials for which are already in the secure storage, the credentials will be updated with data from the CSV file.
The script will create a subfolder called Credentials in the same folder that you saved your CSV file to. The Credentials subfolder will contain a set of folders and files containing credentials and names of computers required to connect to each of the domains. After this you no longer need the csv file. The passwords will be encrypted using the Windows standard Data Protection API, which means that only the user whose credentials were used to launch the PowerShell script (Adaxes default service administrator) will be able to read passwords in those files. Since all scripts are launched in Adaxes with the credentials of the default service administrator, the passwords saved in the secure storage will be accessible for use by Adaxes.
Now, you can create a Custom Command for logging users off:
-
Create a new Custom Command.
-
On the 2nd step of the Custom Command creation wizard, select User.
-
On the 3rd step of the wizard, add the Run a program or PowerShell script action and paste the following script:
Import-Module Adaxes
$credentialDirectoryPath = "C:\PowershellScript\Credentials" # TODO: modify me
$targetUserName = "%username%"
# Get name of the user's domain
$domainName = $Context.GetObjectDomain("%distinguishedName%")
# Get credentials for the domain
if(!(Test-Path -Path $credentialDirectoryPath))
{
$Context.LogMessage("The credentials folder was not found. Make sure that $credentialDirectoryPath exists.", "Error") # TODO: modify me
return
}
$directory = Get-ChildItem -Path $credentialDirectoryPath -Filter $domainName
if(!$directory)
{
$Context.LogMessage("The credentials folder for domain $domainName was not found.", "Error") # TODO: modify me
return
}
# Read credentials for the domain from the file
$file = Get-ChildItem -Path $directory.FullName
if(!$file)
{
$Context.LogMessage("The credentials file for domain $domainName was not found.", "Error") # TODO: modify me
return
}
$userName = (Get-Content -Path $file.FullName)[0]
$passwordEncryptedString = (Get-Content -Path $file.FullName)[1]
$password = ConvertTo-SecureString -String $passwordEncryptedString
$credential = New-Object System.Management.Automation.PsCredential($userName,$password)
# Get all computers from the user's domain
$computers = Get-AdmComputer -Filter {(Enabled -eq $True) -and (operatingSystem -like "*Server*")} `
-AdaxesService localhost -Server $domainName
# Create a remote PowerShell session
$session = New-PSSession $file.Name -Authentication Negotiate -Credential $credential
$result = Invoke-Command -Session $session -ArgumentList $computers, $targetUserName -Scriptblock {
param($computers, $targetUserName)
Import-Module PSTerminalServices
foreach ($computer in $computers)
{
try
{
$session = Get-TSSession -ComputerName $computer.DNSHostName -UserName $targetUserName -State Active
}
catch
{
continue
}
if ($session.ConnectionState -ine "Active")
{
continue
}
try
{
Stop-TSSession -Id $session.SessionID -ComputerName $computer.DNSHostName –Force
return "User $targetUserName has been successfully disconnected from " + $computer.Name
}
catch
{
return $computer.Name + " : " + $_.Exception.Message
}
}
}
Remove-PSSession $session
if($result)
{
$Context.LogMessage($result, "Information")
}
In the script, $credentialDirectoryPath specifies the path to the directory that contains a secure storage with credentials to log on to your domains.
-
Finish creation of the Custom Command.
When executed on a user, the Custom Command will connect to the computer that you specified for the user's domain in the CSV file using the credentials that you provided. When connected, the Custom Command will launch a script on that computer that will log the user off from all sessions.
If you want this Custom Command to be avilable from the Home Page of the Adaxes Web Interface, you need to create a Home Page Action that will execute this Custom Command as described in the Configure Home Page Actions Tutorial. See section Custom Command.