How to run powershell script that doesn't have ps1 extension - powershell

I am using ops tool Rundeck that allows for execution of arbitrary scripts. I enter the script text in the web application widget and upon execution, Rundeck saves it to temporary file and calls interpreter. The problem is that the temporary file doesn't have ps1 extension and Powershell refuses to execute it.
Is there any way to set up Powershell to ignore extension ?
=== EDIT 2018 ===
Rundeck now has an option for this within a job definition.

I know I'm not strictly answering your questions regarding setting up PowerShell to ignore extensions, but here is one way of executing code from a textfile:
Invoke-Command -ScriptBlock ([ScriptBlock]::Create((Get-Content .\file.txt)))
This reads the contents of file.txt and converts it into a scriptblock, before executing it using Invoke-Command.

Related

Execute Batch in Powershell (Win 10) does not affect Parent Shell

just for understanding this.
I want to open my Powershell in a certain folder. As I didn´t find out how, I tried to put a batch file with just "cd ....." in it in the default folder where PowerShell opens.
When I execute the batch, though, I end up where I started from.
It seems that the batch gets excuted in a subshell which doesn´t affect the Parentshell.
How can I execute the stuff in the batchfile in parentshell ?
Thanks in advance!
You cannot. Batch files are executed by cmd, not PowerShell, so there will always be a new process for them.
With a PowerShell script you can use dot-sourcing
. Script.ps1
To execute the script in your current scope, which is most similar to how batch files are executed by cmd by default.
If you want to open your Powershell in a certain folder, you can set that up in your Powershell profile. In Powershell, type $profile and that will give you the location of your profile file. Edit that file and use Set-Location:
Set-Location 'C:\Some\Place'
Powershell will execute whatever is in your profile script every time you open a new Powershell session.

Is it possible to start Powershell ISE with specified (not default) profile?

I want to have several (more than one) PowerShell profiles which will create different environments.
More specifically I need way for start separate PowerShell ISE for work with TFS and other PowerShell ISE instance for regular work. 'TFS' environment require loading some additional snappins, modules, modify prompt and so on. I do not want all this stuff will be executed for regular PowerShell ISE sessions but only when I want to.
I found that I can automatically load arbitrary script through command line parameter -File, but it does not executed automatically..
I do it by creating a shortcut for PowerShell ISE with a default directory :
In the default Directory (here called D:\TFS) I create a .PS1 file called local_profile.ps1.
In the beginning of the current profile file (C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1) I add :
# Try to load local profile
Get-ChildItem "local_profile.ps1" -ErrorAction SilentlyContinue | %{.$_}
You just have to add your initialization code to D:\TFS\local_profile.ps1.
powershell ISE has a profile too.
Probably is something like:
E:\Users\UserName\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1
Or you can open powershell ise and look at $profile variable.
After locate your profile file, write your modules import and custom scripts in it.

Execute any file as powershell script

I encountered a challenge that I failed to resolve the way I wanted it to do.
I got a file that contains a powershell script, but that file does not have the extension assigned to powershell. The question is: How can I execute a powershell in a script file with the wrong file extension (or none)?
Invoke-Expression does not seem to work because it always executes the default action assigned to the file type. If I give that cmdlet a *.txt file the editor pops open.
I know that I can resolve that by renaming the script file or naming it properly in the first place. This is what I ended up doing.
Still I wonder if it is possible to execute a file as a script with the wrong file extension without modifying, renaming or coping the file. And if it is not working… why is that?
Powershell is designed such that executing or dot sourcing a file requires a .ps1 extension, and Powershell.exe will refuse to run any file that doesn't have that extension.
One way to invoke Powershell code from a non-ps1 file is to launch Powershell.exe using STDIN, and pipe your script to it. This requires a new shell, so is not very good for launching scripts from within an existing scripting environment.
Powershell.exe - < thescript.txt
Another way is to create a temporary .ps1 file and execute that. This has the advantage of using the current scripting environment, but requires a temporary file.
Copy-Item -Path '.\thescript.txt' -Dest '.\temp.ps1'
. .\temp.ps1
del .\temp.ps1
In my opinion, the file extension restriction is silly, but that's how it was designed. Apocryphally, this is for security reasons, but I can find no citation to back it up.
Or you use Get-Content to read the file and then invoke that with Invoke-Expression or Invoke-Command -ScriptBlock.

How to use a Jenkins variable in my Powershell Script

I have written a simple script via PowerShell to gather some files and zip them into one folder, lets call it Script.ps1. I want to make the script run every time Jenkins does a new build, however I also would like the name of the zip file to be the BUILD_NUMBER.
How can I create a variable in PowerShell that is Jenkins's current build number? As of the moment I am calling the Script.ps1 in the execute shell section of configuration.
I'm not familiar with Jenkins, but I believe BUILD_NUMBER is an environment variable.
To access it in PowerShell, use $env:BUILD_NUMBER
E.g. If using 7-zip
7z.exe a "$env:BUILD_NUMBER.zip" C:\Build\Path
You can add arguments to your Script.ps1. Just use Param at the top of the script:
Param( $BuildNumber ) #must be first statement in script
# your current script goes here
then you can call the script passing BUILD_NUMBER as argument from Jenkins. Refer to this question for calling Powershell script with argument.
You could also use the Powershell Plugin, see here.
It allows you to enter PowerShell commands directly in a text box in Jenkins.
Then you can use the available environment variables (see docu of the plugin). The usage is a little cryptic:
(Get-Content ./Sources/SlmMachineControl/GUI/Project1.rc).replace("`"FileVersion`", `"1.0.0.0`"" ,"`"FileVersion`" `"2.3.$($env:BUILD_NUMBER).0`"") | Set-Content ./Sources/SlmMachineControl/GUI/Project1.rc
Also note the escaping of the double-quotes. Took me quite a while :)

My PowerShell script only works when running from ISE

I can't post all of the script contenet, but the basic idea is that it downloads JSON and converts it to objects using the ConvertFrom-Json cmdlet. Some objects are filtered out, and the rest are written to an XML/XLS document (in the Excel 2003 format). This file is then attached to an email and sent to various people.
The problem I'm having is that it only works when run from the Powershell ISE. Once I try setting up a scheduled task, calling it from cmd, or even calling it from powershell, the attached file is completely empty. It is as if some functions do not run (the one that loops through and creates all rows).
I can continue to run from ISE for the time being, but the idea of this script is to send out an automatic email that will require no intervention. Any ideas as to what could be causing this?
You need to run the script "dot sourced"
which can be done like this
powershell.exe -noexit -file c:\test.ps1
or
pwershell.exe -noexit ". c:\test.ps1"
See this link under the -File section
http://technet.microsoft.com/en-us/library/hh847736.aspx
Based on the answer from the comments to the original post, it seems that the script was (unexpectedly?) working in the ISE because of the bug/quirk/feature that allows scripts run in the ISE to be aware of variables used in the console window and vice-versa.
This can often cause logic problems or unexpected results when a script runs with a variable already defined (and not initialized carefully in the script).
Ways to avoid this problem:
Try to test your code in as clean an environment as possible.
http://powershell.com/cs/blogs/tips/archive/2015/02/12/getting-a-clean-powershell-environment.aspx
To make sure a script runs in a completely clean test environment, you
could of course restart the PowerShell ISE. A more convenient way is
to open another PowerShell tab: in the PowerShell ISE, choose File/New
PowerShell Tab.
Use Set-StrictMode 2 in your script to catch undefined variables, etc.
https://technet.microsoft.com/en-us/library/hh849692.aspx
Set-StrictMode -Version 2.0
Prohibits references to uninitialized variables (including uninitialized variables in strings).
Prohibits references to non-existent properties of an object.
Prohibits function calls that use the syntax for calling methods.
Prohibits a variable without a name (${}).
I have had this problem be for and for me executing the scrip using single-threaded function from powershell worked.
You could also try some other options, go to this link to find more info.
Example
powershell.exe -noexit c:\test.ps1 -sta
Change the missing variable or function to global.
function global:mycall{}
Start your Script with:
[cmdletbinding()]