Executing Powershell script via BatAction

I have been trying to send HTTP request using powershell but I run into some issues.

First, some of the cmdlet commands are not recognized by Milestone when BatAction triggers powershell script. Example, Invoke-Webrequest, start-process, -File location and more.

I want to be able to open chrome or Microsoft edge and then pass arguments to it.

Here is the line that I want to use:

Start-Process -FilePath $BrowserLocation -ArgumentList "www.google.com, ‘-headless’

This line works fine outside milestone and all my services are running with an administrator account. I understand BatAction may have a limitation to what I can access outside milestone.

Can I have a list of what cmdlets I can use?

I also tried to use ‘curl’ which works perfectly with milestone but my request returns nothing (that’s expected) which causes ‘curl’ to fail as it expects content.

Hi Saad,

The limitation you’re running into is not related to BatAction or Milestone in any way. There’s nothing in either that could possibly limit your access to PowerShell cmdlets.

my guess is that you’re running into something like constrained language mode when running PowerShell under the context of the Event Server service account.

See if you can run PowerShell interactively under the same user account as the Event Server service and whether you run into an issue there.

If Event Server runs as network service, you can use psexec to start PowerShell as that special account…

psexec -I -u “NT AUTHORITY\NETWORK SERVICE” powershell.exe

If it works from an interactive PowerShell prompt under the same service account, then maybe you have a domain or local security policy limiting the scope of what a non-interactive user can do?

As a diagnostic, try making your BatAction script dump all the session variables and their values along with all the environment variables. Look for things like constrained language mode, check the PSModulePath to see if that user is missing normal module paths.

I’ve used BatAction to launch PowerShell with some advanced scripts without issue, so I’m quite sure this won’t be a restriction by the VMS. The plugin does nothing more than launch an executable with some VMS information passed in as arguments.

We’d love to know what the issue ended up being - please share when you find out so we can offer more targeted advice in the future!

Hi Josh,

About my environment:

  • OS: Windows Server 2016 Datacenter
  • Milestone Version: Essential+ 2020 R3
  • MIPS is installed
  • No Firewall blocking any traffic from my workstation
  • All Milestone’s services are running under the administrator account

If there is no limitation from BatAction or Milestone, I am speechless then.

Note I can run any PowerShell scripts outside Milestone with no issue whatsoever.

I’ve added ‘Network service’ account to administrator group (just in case). All Milestone services are running under the administrator account. All milestone’s folders have proper permission to the admin account by default and I rechecked them.

There is no Constrained Language in my PowerShell settings. Here is the result from my PowerShell windows.

PS C:\> $ExecutionContext.SessionState.LanguageMode
FullLanguage

Here is a simple example. Milestone will trigger the PS script in which it will only output content to file. It’ll skip launching chrome and python script and it throws no error after completion.

# Set the location of the log directory 
$workingDir = Join-Path $env:ProgramData 'Milestone\BatAction\'
 
# Create a directory
$null = New-Item -Path $workingDir -ItemType Directory -Force
 
# Set the location of BatAction log
$transactionLogPath = Join-Path $workingDir 'BatAction.log'
 
 
# Define timestamp function 
function Get-Time {Get-Date -Format "MM-dd-yyyy HH:mm:ss -"}
 
try{
    # Example 1 
    Start-Process -FilePath 'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
 
    # Example 2
    python 'C:\Users\Administrator\Desktop\Hello.py'
 
    # Write to log 
    "$(Get-Time) Output Deactivated" | Tee-Object -FilePath $transactionLogPath;
    
    #Check who runs the script 
    "$env:userdomain\$env:username" | Tee-Object -FilePath $transactionLogPath -a;
}
 
catch 
{
    "$(Get-Time) An error occurred. $_" | Tee-Object -FilePath $transactionLogPath -a;
}

from the above script you can see, I added a line to see who runs the script. After BatAction triggers, here is the output

01-29-2022 16:35:52 - Output Deactivated
ComputerName\Administrator
 

Furthermore, I’ve tested these example in different workstations and VMC product (Expert). This is my sixth script that I designed to do the same task I originally intended to do with no luck.

Now regarding the cmdlest “Invoke-WebRequest”, I found that I needed convert the credentials to “ToBase64String” and pass it to a header using “Basic Authentication”.

When I invoke the URL on Web browser, Linux terminal, Python, PHP, C++ script, it works with no error. It seems “Invoke-WebRequest” doesn’t know how to handle the request if authentication type is not specified (At least this is case in my situation).