Executing Powershell script specifying the user

Hello everyone,

I'd like to execute a Powershell script that creates a folder, but I need to run it with a specific user that has the right permissions. The idea is to execute the script in a way that resembles the "run as user:\ ..." in the cmd.

I made a process that executes the script but I don't know how to recall the credentials, that I stored in the configuration parameters as encrypted.

Can someone help me find a way?

Thank you in advance,

Lucrezia

Parents
  • Hi Lucrezia

    I am not sure which process component you are using in your process, but I assume you may be using a remote PS session to create the folder.

    PowershellComponentNet4 components provide a number of options to run Powershell commands and scripts, including ExecuteRemoteHostScript which already has remote PS session parameters in the component.

    It is the job server that executes the process step and can decrypt values using the private key. If encrypted parameter values are used, the job server needs to know which parameters to decrypt.

    The encrypted configuration parameter value can be passed into the process step and then the encrypted parameter needs to be marked as encrypted.

    hth 

  • Hi Steve,

    unfortunately this component is not the one we've been looking for, as we want to execute the script locally. We weren't able to find another component that takes as input username and password but executes scripts locally, you know if it does exist?

    Thank you for your answer,

    Lucrezia

  • Hi Lucrezia

    OK, so this needs to be executed locally on the job server. Can I ask what version of OneIM you have? You said you have a process working, are you using the PowershellComponentNet4 - ExecuteScript task? Are you able to share the PS script that you are using?

    In the meantime, you might find this discussion useful. It an old discussion but should still be relevant.

     RE: Decrypt value in process task "PowerShellComponent - Execute Script" 

    There is an option to create a script process step to decrypt the password and pass it as an OUT variable to your PS script. There are some disadvantages with this option as you see discussed in the link.

    There may also be an option to create a custom function form your code. You could then use the ExecuteCommand process task passing in the credentials using these parameters. This option would, most likely, be the most secure.

    Both of these options are discussed in the link.

    hth

  • Hi Steve,

    sorry for the late answer. Your link was very useful, now I'm trying to use the ExecuteCommand task as suggested by Markus, and fill the variables using the job parameters. 

    Now my issue is: how I pass the parameters in the script? I have two parameters in the process step, called "Param_username" and "Param_password", the latter is hidden and encrypted.

    For now, I'm trying with this script but I'm getting the error "The term is not recognized as a name of a cmdlet":

    Imports System
    Imports System.Collection.Generic
    Dim script As New StringBuilder()
    
    script.Append(String.Format("$$securepassword = ConvertTo-SecureString {0} -AsPlainText -Force", "$args[0]"))
    script.Append(Environment.NewLine)
    script.AppendLine(String.Format("$$credential = New-Object System.Management.Automation.PSCredential -ArgumentList ({0}, $$securePassword)", "$args[1]"))
    
    Value = script.ToString()

  • Hi Lucrezia

    The code is creating a powershell script which is used in the ExecuteScript task and not in the ExecuteCommand task.

    In the ExecuteCommand task there is the Command parameter to enter a cmdlet or function.

    I do not know the Powershell commands that you want to execute but as indicated in the article you could create a custom Powershell function that addresses your requirement and then pass in the parameters to the function.

     

     

    If you are using the New-Item cmdlet then I think the -credential parameter is not supported

    New-Item (Microsoft.PowerShell.Management) - PowerShell | Microsoft Learn

    hth

  • Hello,

    I created the function as you suggested, but where do I have to save it? Do I have to import it in any way? 
    I trivially saved it in a folder but obviously OneIM doesn't know how to find it and returns me the error "The term New-CustomerFolder is not recognized as the name of a cmdlet".

    Lucrezia 

  • Hi

    Yes, if you use the custom function option then it needs to be available in Powershell on the machine that you are using to execute the command.

    Slightly drifting into a Powershell configuration topic here.

    Powershell Functions are typically put inside a Powershell script module (psm1) so they can be called without knowing the physical location.

    If you are intending to put your function into a module, then you could install the custom module (Install-Module) or

    Import the module on your local machine (Import-Module). You could use a Powershell profile to import the custom module for each Powershell session.

    https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-5.1

  • Hello again Steve :)

    It seems like I'm proceeding but not reaching the objective. For now the code of my function is this.

    function New-HomeFolderMain
    
    {
    
    param(
    
    [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    
    [ValidateNotNullOrEmpty()]
    
    [String]$Username,
    
    [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    
    [ValidateNotNullOrEmpty()]
    
    [String]$Password
    )
    
    $SecurePassword = convertto-securestring -AsPlainText -Force -String $Password
    
    $cred = New-object System.Management.Automation.PSCredential -ArgumentList($Username, $SecurePassword)
    
    Invoke-Command -ComputerName localhost -Credential $cred ScriptBlog ${function:New-HomeFolder}

    In the function "New-HomeFolder" the domain controller is called and then a folder is created. The issue here is that the Active Directory domain is not found (command "Get-ADDomain"), while if I run it in the shell it finds the name of domain.

    I don't want to ask too many Powershell technical things, I was just wondering if this is the right way to call a function from One Identity? Is the credentials object working in the right way? Maybe One Identity is calling again the function with Local System Account?

    Thank you again,

    Lucrezia

  • The Powershell command is started in the context of the Job Service, then it is started in the context of the user running the Job Service.

  • Hello Markus,

    thanks for the answer. I checked the contexts and the function New-HomeFolder, called with Invoke-Command, is correctly invoked with the user I want (the one present in the $cred variable). 
    From the shell this user can retrieve the ADDomain, but when the script is called from One Identity it won't happen.

    What's the difference?

  • I do not want to dive into details of PowerShell but the commands executed by invoke-command are executed on the remote server with the credentials you are specifying. But the AD management module is not imported in that session.

  • My script contains the import of AD module (e.g. Import-Module ActiveDirectory)
    The problem here is that when the script is called from One Identity it won't read the domain, but when it's called from the shell it will; both operations done with the same credentials.

Reply Children
  • Hi

    If you are using the powershell AD module then it sounds as though your use case is a bit more than your original post: "creating a folder on a localhost in the context of specific user." 

    Creating a folder "locally" under the context of a specific user is possible using the Invoke-command. I am not sure what commands you are running in your script.

    Maybe delving into PS a bit but for sure you need to have the modules available to the sessions and also I am not 100% sure you can use the localhost as the computer name when running AD module commands in a non interactive session.

    You could try using the domain controller FQDN. 

    function New-CustomFolder  
    {
        
        param(
    		    [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][ValidateNotNullOrEmpty()][String]$User,
    			[parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][ValidateNotNullOrEmpty()][String]$Password,
    			[parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)][ValidateNotNullOrEmpty()][String]$ScriptblockString
            )
    			# credentials of the specific user
    			$SecurePassword = convertto-securestring -AsPlainText -Force -String $Password
    			$cred = New-object System.Management.Automation.PSCredential –ArgumentList ($User,$SecurePassword)	
    			# convert the string into scriptblock
          		$Scriptblock = [scriptblock]::Create($ScriptblockString)
    			# run the command in the scriptblock in the context of the specific user
        		Invoke-Command -ComputerName <domain controller FQDN> -Credential $Cred -ScriptBlock $Scriptblock
     }

  • Hello Steve,

    this was the piece of information I was missing! I'm sorry for the misunderstanding, I have difficulties explaining as I know very little about these matters. With "locally" I meant that the script exists in the local machine and the call to the script has to happen locally (I was said remote execution is not permitted in this architecture). Probably I confused the concepts.

    All your feedbacks allowed me to find the solution, so, thank you all!

    Lucrezia