0

I have the following command that I can run in cmd.exe:

"C:\Program Files (x86)\FireEye\xagt\xagt.exe" -g "C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"

I just need to run the above mentioned command in PowerShell.

I tried to use the symbol & before the command, but I got an error. I also tried to use the following commands:

###########################
$cmd = 'C:\Program Files (x86)\FireEye\xagt\xagt.exe'
$arg1 = '-g C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt'
& $cmd $arg1
########################################

Start-Process -FilePath "xagt.exe" -WorkingDirectory "C:\Program Files (x86)\FireEye\xagt" -ArgumentList "-g "C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt""
############################################

PS C:\Program Files (x86)\FireEye\xagt> & 'xagt.exe -g "C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%%date:~-7,
_%time:~0,2%%time:~3,2%%time:~6,2%.txt"'
& : The term 'xagt.exe -g
"C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"' is not
recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if
a path was included, verify that the path is correct and try again.
At line:1 char:3
+ & 'xagt.exe -g "C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%% ...
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (xagt.exe -g "C:...time:~6,2%.txt":String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

PS C:\Program Files (x86)\FireEye\xagt> Invoke-Command -ScriptBlock {
>>        xagt.exe -g "C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6
%.txt"
>> }
xagt.exe : The term 'xagt.exe' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:2 char:8
+        xagt.exe -g "C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10 ...
+        ~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (xagt.exe:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

All trials were not successful , there is something in thd syntax that I cannot understand.

mklement0
  • 382,024
  • 64
  • 607
  • 775

3 Answers3

1

This is a legacy command line way to create a date stamp on your file:

%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%

Use the powershell command instead:

(Get-Date).ToString('yyyymmdd_HHmmss')

This is a legacy command line way to get computername:

%computername%

Use the powershell command instead:

$env:COMPUTERNAME

Try declaring your path and Outputfile path in powershell first then just call the exe with these set variables:

$WorkingDir = "C:\Program Files (x86)\FireEye\xagt"
$OutputFile = "C:\Temp\xagt_" +[string]$env:COMPUTERNAME + "_" + [string]((Get-Date).ToString('yyyymmdd_HHmmss')) + ".txt"

cd $WorkingDir
.\xagt.exe -g $OutputFile
  • There are many ways to start an exe in powershell, the method described is the most simple and should meet your needs.
Mike Q
  • 6,716
  • 5
  • 55
  • 62
  • Some good pointers, but I wouldn't recommend using `cd` (`Set-Location`) in a PowerShell script, as the current location invariably changes _for the whole session_. Also, environment variables are always strings, and `.ToString()` obviously also returns a string, so your `[string]` casts are unnecessary. A more PowerShell-idiomatic solution would be to use string interpolation: `"C:\Temp\xagt_${env:COMPUTERNAME}_$((Get-Date).ToString('yyyymmdd_HHmmss')).txt"` – mklement0 Mar 22 '23 at 20:31
  • @mklement0 Eh, not saying you are wrong by any means but I don't think a new coder needs this level of detail. I removed the word "DOS" since it's apparently triggering. The other comment is a matter of taste.. I do prefer your line but I was trying to keep it simple I suppose at the time I wrote mine. – Mike Q Mar 23 '23 at 00:01
  • If by "triggering" you mean "triggering valid criticism of technically incorrect and potentially confusing terminology", I agree. Replacing "DOS" with "legacy" is an improvement, but an inadequate one. Yes, you could consider the choice between string concatenation with `+` and expandable strings (string interpolation) a matter of taste. By contrast, use of redundant `[string]` casts and unqualified use of `cd` are not, to the detriment of readers who aren't PowerShell experts. – mklement0 Mar 23 '23 at 01:50
0

I run the command using the following syntax

cd "C:\Program Files (x86)\FireEye\xagt\"
cmd /c xagt.exe -g "C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt"
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

tl;dr

Delegate the entire call to cmd.exe, passing it as a single string ('...') to cmd /c:

cmd /c ' "C:\Program Files (x86)\FireEye\xagt\xagt.exe" -g "C:\tmp\xagt_%computername%_%date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt" '

Background information:

  • You're using cmd.exe-format environment-variable expansions (e.g., %computername%, %date:~-4,4%), which PowerShell doesn't support, so you indeed must call via cmd.exe

    • The alternative is to use equivalent PowerShell constructs, as shown in Mike Q's answer.
  • If the need to call via cmd.exe weren't in the picture:

    • You would indeed need &, the call operator in order to invoke your executable, given that its path is (of necessity) quoted (see this answer for why this is needed).

    • Nothing else would need to change; that is, arguments to pass to your executable still need to be passed individually - you cannot pass them as a single string.

      # To illustrate the syntax, using a simplified -g argument.
      & "C:\Program Files (x86)\FireEye\xagt\xagt.exe" -g "C:\tmp\foo.txt"
      
      # !! BROKEN - do NOT use a *single string* for the arguments.
      # If you wanted to provide the arguments via a variable, use an *array*
      #    $passThruArgs = @('-g', 'C:\tmp\foo.txt')
      $passThruArgs = '-g "C:\tmp\foo.txt"'
      & "C:\Program Files (x86)\FireEye\xagt\xagt.exe" $passThruArgs
      
  • While your own answer works, it uses cd (a built-in alias of the Set-Location cmdlet), but there is no need for it, especially given that Set-Location is best avoided in scripts, given that in PowerShell changing the location invariably affects the whole session.

    • If you do need to change the current location (working directory), use the following idiom to ensure that the previous location is restored on exiting the script:

      try {
      
        # Switch to the desired location, saving the current one.
        # In this example, the script's own dir. is switched to.
        Push-Location $PSScriptRoot
      
        # ... work in the new location.
      
        # Sample commands: Show the now current location and wait for
        # the user to press Enter. If you abort the script with Ctrl-C
        # at that point, the `finally` clause still executes and restores the
        # original location.
        $pwd | Out-Host
        pause
      
      } finally {
        # Restore the previous location,
        # even if the script was aborted.
        Pop-Location
      }
      
mklement0
  • 382,024
  • 64
  • 607
  • 775