2

Is it possible to write self-modifying PowerShell scripts?

Suppose I have a script named foo.ps1:

"Write-Host `"Goodbye world`"" | Set-Content "foo.ps1"
Write-Host "Hello world"

This script prints out Hello world. What techniques could I use to get it to print out Goodbye world?

sourcenouveau
  • 29,356
  • 35
  • 146
  • 243

2 Answers2

1

To me it does not make sense, after you have modified a script, you need to re-dotsource it in order to get new statments.

This script changes itself three times:

Write-Host "Hello world"
"Write-Host `"Goodbye world`"" | Set-Content "foo.ps1"
. .\foo.ps1
"Write-Host `"Is really useful?`"" | Set-Content "foo.ps1"
. .\foo.ps1

and prints:

Hello World
Goodbye World
Is really useful?

Another possibility is to write a script which accepts as input parameters script blocks.

Emiliano Poggi
  • 24,390
  • 8
  • 55
  • 67
  • The example script I provided is trivial and contrived; there are lots of potential uses for self-modifying code (http://stackoverflow.com/questions/516688/what-are-the-uses-of-self-modifying-code). Your idea to dot-source the script is one answer to my question. I'm curious if there are other techniques for changing a script as it runs. – sourcenouveau Apr 27 '11 at 16:06
  • You asked for a self-modifying script. There is no other ways to load new data in the current working session, than dot-source. – Emiliano Poggi Apr 27 '11 at 19:24
  • Powershell is not really the proper language here. You might be interested in this [thread](http://stackoverflow.com/questions/3057487/self-modifying-code). – Emiliano Poggi Apr 27 '11 at 19:32
  • You could have some kind of master Driver script, that is kicked off by the user. It then calls a subscript and dot sources it.. That script could modify itself and then send a return code that it should be reran and re-dot sourced. As stated above, PowerShell isn't really build for these kinds of lofty concepts in mind. – Daniel Richnak Apr 27 '11 at 22:28
  • There's definitely uses for things like this. I'm trying to use it in nuget package manager (except it isn't self-modifying per se - it updates itself and then re-invokes with an 'ok I'm updated' argument). I haven't solved how to do this properly, though. :( – aikeru Sep 18 '13 at 15:35
  • 1
    It can be useful for persisting settings the next time you run the script. i.e. if([string]::IsNullOrWhiteSpace($projPath)) { $projPath = Read-Host -Prompt "Where is the project file?" } Now we can save that in the script so next time we don't need to ask. (sorry, comments are not meant for code) – Tom Padilla Feb 28 '17 at 14:27
-1

Yes you an however I would be there is a better way to do what you and to accomplish.

C:(...)WindowsPowerShell >.\foo.ps1
Hello world
C:(...)WindowsPowerShell >.\foo.ps1
Goodbye world
C:(...)WindowsPowerShell >
rerun
  • 25,014
  • 6
  • 48
  • 78
  • I would like to my script to be called *once* from the command line. With that in mind, you are basically suggesting that my script call itself after modifying itself. – sourcenouveau Apr 27 '11 at 15:37