It is popular request to launch MMC snap-ins through PSM. CyberArk does not have a clear and detailed guide to show how to configure this. I did some research and found following steps working for me.
Download and install AutoIT3 on PSM server
You might get an issue to launch an application, in this case, from PSM server, un-comment following lines in C:\Program Files (x86)\CyberArk\PSM\Hardening\PSMConfigureAppLocker.xml and executed PSMConfigureAppLocker.ps1 afterwards which completed successfully.
<Application Name=”MMC” Type=”Exe” Path=”C:\Windows\System32\mmc.exe” Method=”Hash” /><Application Name=”Notepad” Type=”Exe” Path=”C:\Windows\System32\notepad.exe” Method=”Hash” />
Create your own AutoIt3 script
Cloned C:\Program Files (x86)\CyberArk\PSM\Components\PSMAutoItDispatcherSkeleton.au3, and rename your copy as PSMAutoItDispatcherMMC.au3
Chang/add following in PSMAutoItDispatcherMMC.au3:
Global Const $DISPATCHER_NAME = “Microsoft ADUC” ; CHANGE_ME
Global Const $CLIENT_EXECUTABLE = ‘mmc “c:\windows\system32\services.msc” -a /computer=’ & $TargetPSMRemoteMachine
Global $ConnectionClientPID = RunAs ($TargetUsername,$TargetLogonDomain,$TargetPassword,2,$CLIENT_EXECUTABLE)
add following:
Func FetchSessionProperties() ; CHANGE_ME
if (PSMGenericClient_GetSessionProperty(“LogonDomain”, $TargetLogonDomain) <> $PSM_ERROR_SUCCESS) Then ;Added CWA
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
if (PSMGenericClient_GetSessionProperty(“PSMRemoteMachine”, $TargetPSMRemoteMachine) <> $PSM_ERROR_SUCCESS) Then ;Added CWA
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
#AutoIt3Wrapper_UseX64=n
Opt("MustDeclareVars", 1)
AutoItSetOption("WinTitleMatchMode", 3) ; EXACT_MATCH!
AutoItSetOption("WinDetectHiddenText",1)
;============================================================
; PSM AutoIt Dispatcher Skeleton
; ------------------------------
;
; Use this skeleton to create your own
; connection components integrated with the PSM.
; Areas you may want to modify are marked
; with the string "CHANGE_ME".
;
; Created : April 2013
; Cyber-Ark Software Ltd.
;============================================================
#include "PSMGenericClientWrapper.au3"
;=======================================
; Consts & Globals
;=======================================
Global Const $DISPATCHER_NAME = "Microsoft Services" ; CHANGE_ME
;Global Const $CLIENT_EXECUTABLE = 'mmc "C:\Windows\System32\services.msc"'
Global Const $ERROR_MESSAGE_TITLE = "PSM " & $DISPATCHER_NAME & " Dispatcher error message"
Global Const $LOG_MESSAGE_PREFIX = $DISPATCHER_NAME & " Dispatcher - "
Global $TargetUsername
Global $TargetPassword
Global $TargetAddress
Global $TargetLogonDomain
Global $TargetPSMRemoteMachine
;Global Const $CLIENT_EXECUTABLE = 'mmc "c:\windows\system32\services.msc" -a /computer=' & $TargetPSMRemoteMachine
Global $ConnectionClientPID = 0
;=======================================
; Code
;=======================================
Exit Main()
;=======================================
; Main
;=======================================
Func Main()
; Init PSM Dispatcher utils wrapper
ToolTip ("Initializing...")
if (PSMGenericClient_Init() <> $PSM_ERROR_SUCCESS) Then
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
LogWrite("successfully initialized Dispatcher Utils Wrapper")
; Get the dispatcher parameters
FetchSessionProperties()
Global Const $CLIENT_EXECUTABLE = 'mmc "c:\windows\system32\services.msc" -a /computer=' & $TargetPSMRemoteMachine
$ConnectionClientPID = RunAs($TargetUsername,$TargetLogonDomain,$TargetPassword,2,$CLIENT_EXECUTABLE,"",@SW_SHOWMAXIMIZED)
LogWrite("mapping local drives")
if (PSMGenericClient_MapTSDrives() <> $PSM_ERROR_SUCCESS) Then
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
LogWrite("starting client application")
ToolTip ("Starting " & $DISPATCHER_NAME & "...")
; ------------------
; Handle login here! ; CHANGE_ME
; ------------------
; Execute RunAs command to run ssms under the PSM Shdaow User's profile, but pass the network credentials of
; the target (specified by the "2" logon type)
if ($ConnectionClientPID == 0) Then
Error(StringFormat("Failed to execute process [%s]", $CLIENT_EXECUTABLE, @error))
EndIf
; Send PID to PSM as early as possible so recording/monitoring can begin
LogWrite("sending PID to PSM")
if (PSMGenericClient_SendPID($ConnectionClientPID) <> $PSM_ERROR_SUCCESS) Then
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
; Terminate PSM Dispatcher utils wrapper
LogWrite("Terminating Dispatcher Utils Wrapper")
PSMGenericClient_Term()
Return $PSM_ERROR_SUCCESS
EndFunc
;==================================
; Functions
;==================================
; #FUNCTION# ====================================================================================================================
; Name...........: Error
; Description ...: An exception handler - displays an error message and terminates the dispatcher
; Parameters ....: $ErrorMessage - Error message to display
; $Code - [Optional] Exit error code
; ===============================================================================================================================
Func Error($ErrorMessage, $Code = -1)
; If the dispatcher utils DLL was already initialized, write an error log message and terminate the wrapper
if (PSMGenericClient_IsInitialized()) Then
LogWrite($ErrorMessage, True)
PSMGenericClient_Term()
EndIf
Local $MessageFlags = BitOr(0, 16, 262144) ; 0=OK button, 16=Stop-sign icon, 262144=MsgBox has top-most attribute set
MsgBox($MessageFlags, $ERROR_MESSAGE_TITLE, $ErrorMessage)
; If the connection component was already invoked, terminate it
if ($ConnectionClientPID <> 0) Then
ProcessClose($ConnectionClientPID)
$ConnectionClientPID = 0
EndIf
Exit $Code
EndFunc
; #FUNCTION# ====================================================================================================================
; Name...........: LogWrite
; Description ...: Write a PSMWinSCPDispatcher log message to standard PSM log file
; Parameters ....: $sMessage - [IN] The message to write
; $LogLevel - [Optional] [IN] Defined if the message should be handled as an error message or as a trace messge
; Return values .: $PSM_ERROR_SUCCESS - Success, otherwise error - Use PSMGenericClient_PSMGetLastErrorString for details.
; ===============================================================================================================================
Func LogWrite($sMessage, $LogLevel = $LOG_LEVEL_TRACE)
Return PSMGenericClient_LogWrite($LOG_MESSAGE_PREFIX & $sMessage, $LogLevel)
EndFunc
; #FUNCTION# ====================================================================================================================
; Name...........: PSMGenericClient_GetSessionProperty
; Description ...: Fetches properties required for the session
; Parameters ....: None
; Return values .: None
; ===============================================================================================================================
Func FetchSessionProperties() ; CHANGE_ME
if (PSMGenericClient_GetSessionProperty("Username", $TargetUsername) <> $PSM_ERROR_SUCCESS) Then
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
if (PSMGenericClient_GetSessionProperty("Password", $TargetPassword) <> $PSM_ERROR_SUCCESS) Then
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
if (PSMGenericClient_GetSessionProperty("Address", $TargetAddress) <> $PSM_ERROR_SUCCESS) Then
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
if (PSMGenericClient_GetSessionProperty("LogonDomain", $TargetLogonDomain) <> $PSM_ERROR_SUCCESS) Then ;Added CWA
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
if (PSMGenericClient_GetSessionProperty("PSMRemoteMachine", $TargetPSMRemoteMachine) <> $PSM_ERROR_SUCCESS) Then ;Added CWA
Error(PSMGenericClient_PSMGetLastErrorString())
EndIf
EndFunc
Create a new connection component
From Administration > Options > Connection components
Create a new PSM Connection Component by Cloned “PSM-VNCClientSample” to create an customized component and set the following options:
Assign this new PSM connection component to Platform
Create an account to test
PSMSR606E