2

I have a Commands.csv file like:

| Command                                        |
| -----------------------------------------------|
|(Get-FileHash C:\Users\UserA\Desktop\File1).Hash|
|(Get-FileHash C:\Users\UserA\Desktop\File2).Hash|
|(Get-FileHash C:\Users\UserA\Desktop\File3).Hash|

Header name is "Command"

My idea is to:

  1. Use ForEach ($line in Get-Content C:\Users\UserA\Desktop\Commands.csv ) {echo $line}
  2. Execute $line one by one via powershell.exe, then output a result to a new .csv file - "result.csv"

Can you give me some directions and suggestions to implement this idea? Thanks!

4
  • Use Import-Csv path | % { & $_.Command } Commented Aug 13, 2022 at 14:54
  • Hello Abraham, thanks for you advice. However, I got an error "BadExpression" around "{ & $_.Command }" Commented Aug 13, 2022 at 16:41
  • That will only work if your file has as its first line a header row with, in your case, a single header: Command or, if your file lacks a header row, use the -Header parameter to declare a single column header: Import-Csv <path> -Header Command. It would be a good idea to edit your question and put your sample data in a code block rather than a table -- it's not obvious if "Commands" is the first row or not. Commented Aug 13, 2022 at 17:06
  • 1
    @AbrahamZinala, &, when given a string, only supports command names / paths, not full commands. Commented Aug 13, 2022 at 17:07

1 Answer 1

5

Important:

  • Only use the technique below with input files you either fully control or implicitly trust to not contain malicious commands.

  • To execute arbitrary PowerShell statements stored in strings, you can use Invoke-Expression, but note that it should typically be avoided, as there are usually better alternatives - see this answer.

  • There are advanced techniques that let you analyze the statements before executing them and/or let you use a separate runspace with a restrictive language mode that limits what kinds of statements are allowed to execute, but that is beyond the scope of this answer.


  • Given that your input file is a .csv file with a Commands column, import it with Import-Csv and access the .Commands property on the resulting objects.

    • Use Get-Content only if your input file is a plain-text file without a header row, in which case the extension should really be .txt. (If it has a header row but there's only one column, you could get away with Get-Content Commands.csv | Select-Object -Skip 1 | ...). If that is the case, use $_ instead of $_.Commands below.
  • To also use the CSV format for the output file, all commands must produce objects of the same type or at least with the same set of properties. The sample commands in your question output strings (the value of the .Hash property), which cannot meaningfully be passed to Export-Csv directly, so a [pscustomobject] wrapper with a Result property is used, which will result in a CSV file with a single column named Result.

Import-Csv Commands.csv |
  ForEach-Object {
    [pscustomobject] @{ 
      # !! SEE CAVEAT AT THE TOP.
      Result = Invoke-Expression $_.Commands 
    }
  } |
  Export-Csv -NoTypeInformation Results.csv
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.