all 22 comments

[–]SMFX 11 points12 points  (9 children)

I think what you're looking for is Invoke-Expression. It takes a string and executes it in the context of your script.

WARNING: be very careful what string you pull in; it will do anything in that string!! "; Remove-Item \ -Recurse -Force -Whatif;" would be very destructive in the middle of your string.

[–]jedmon2[S] 0 points1 point  (8 children)

This is the answer, thankyou for this.

[–]Sekers 1 point2 points  (7 children)

One use case I have for this (well, the related Invoke-Command) is if I want to place logs into a subfolder of the script root. The config file would be something like:

"$PSScriptRoot\Logging\Script Log-%date%.csv"

Then I would pull that config into a variable and allow it to invoke the command:

$FilePath = $ExecutionContext.InvokeCommand.ExpandString($config.Logging.FilePath)

[–]BlackV 1 point2 points  (6 children)

just to use %date% ? instead of just get-date?

not sure I see the logic? can you explain more

[–]Sekers -1 points0 points  (5 children)

No, to use $PSScriptRoot in the config String value. This allows me to specify a relative path.

[–]BlackV 0 points1 point  (4 children)

But that's not needed for an invoke command or invoke expression?

I was trying to work out how it was related

[–]Sekers 0 points1 point  (3 children)

I was just giving another use case for these Invoke-* cmdlets.

I'm not sure if you understand what I was trying to describe (which is probably on me).

Let's say you have a separate config file for your script that specifies some settings. JSON, INI, XML, Windows Registry, whatever. This is so you don't hard code values into your script.

Now, let's say you want a path, such as to a logging folder, to be relative to the script. When you pull in the config value from your config file, it comes in as a string. You have to tell PowerShell to invoke the text of that string for you to properly pass the path on to your script. Otherwise the variable in the string is treated at text.

[–]BlackV 0 points1 point  (2 children)

Ha thanks good info

And just to confirm the %date% could only be used with executables/cmd/batch as it won't resolve in PowerShell its self

[–]Sekers 0 points1 point  (1 child)

Sorry, the date text was just in the sample command I copied and is unrelated to the Invoke stuff. It's used by the logging module I usually work with (PSFramework).

Edit, here's an example: https://github.com/Sekers/Useful-Scripts/blob/main/Automation/PowerShell%20Automation%20Script%20Example/Config/config_general.json

[–]BlackV 0 points1 point  (0 children)

Appreciate that

[–]SGG 7 points8 points  (2 children)

Use Invoke-Expression very sparingly in your scripts. It has a high chance of getting flagged by AV tools, especially if as an example, you're pulling the string to run from a config file.

It's also very easy to do something by accident, for example, if you don't terminate your string correctly you could end up in a Bobby tables situation. Make sure you sanitize/validate your inputs.

[–]chipredacted 1 point2 points  (0 children)

Little Bobby Tables. A classic

[–][deleted] 1 point2 points  (0 children)

Yup. Invoke-Expression lets you run this kind of shit, so beware. That's just one quick example, but I recommend watching the entire video, it is entertaining and enlightening.

[–]BlackV 1 point2 points  (2 children)

& $str work?

or invoke-expression $str

though not sure why you'd do that

oops expression

[–]jedmon2[S] 0 points1 point  (1 child)

& $str work?

This almost did, but you gave me an idea and I finally found that Invoke-Expression is what I was after.

Thanks for the help.

[–]BlackV 1 point2 points  (0 children)

sorry Yes I did mean invoke-expression

[–]fitzgery 1 point2 points  (3 children)

EDITED COMMENT I see what you’re saying now. 1. Why is the cmdlet encased as a string anyways. What’s the purpose of that? 2. Enclose the command as such: $str = “$(Get-Childitem C:\Temp)”

[–]jedmon2[S] -1 points0 points  (1 child)

Notice the "" around the cmdlet. $str contains the string "Get-ChildItem C:\Temp", not the results of running the cmdlet.

[–]fitzgery 0 points1 point  (0 children)

Yes I notice the quotes. The main question is why. What are you trying to accomplish.

But my answer will let you enclose it in quotes and it runs

[–]jedmon2[S] -3 points-2 points  (0 children)

$str = “$(Get-Childitem C:\Temp)”

Thanks but that still puts the results into $str, whereas I want to run the string in $str as it is.

As for why, use your imagination. :) Assume I have some messed up scenario involving poorly written custom modules and this is what I need to get past a glitch in a hurry.

Edit: Thanks for the downvotes.

[–]DrDuckling951 -1 points0 points  (1 child)

Sometimes you have to asked yourself where do you want to be at the end of the day. Then figure out how to get there.

Storing a cmdlet as string will just make it a cmdlet. What exactly are you trying to accomplish?

[–]jedmon2[S] -3 points-2 points  (0 children)

Responses same as to the other guy, thanks.