How to call PowerShell script from WSL?
Asked Answered
S

6

17

In my Windows directory

C:\Users\jholmes\pichak\analytics

I have run1.ps1 code. I run wsl.exe, now my pwd is

   /mnt/c/WINDOWS/system32

How to point to the first path and execute the script?

Stablish answered 11/6, 2021 at 13:58 Comment(4)
Hey did you try traversing back? cd .. from your PWD and traverse to \Users\jholmes\pichak\analytics ? Also how do you want to execure .ps1 scripts in linux?Flyte
@Flyte Impossible,I am still in Linux after cd ..Stablish
I'm not sure i understand your question. If you are already inside Ubuntu or any subsystem, the mount point for accessing windows directories is mnt/ you can traverse to any windows volume from the mnt/ for example. /mnt/c/Users/jholmes/pichak/analytics would be accessible from your linux subsystem. Im not sure what you mena when you say i run wsl.exe. If this isnt the case I might be completely wasting your time as well. lol.. sorryFlyte
If you wish to run windows tools (like powershell) from Linux please see : learn.microsoft.com/en-us/windows/wsl/… , if you wish to do it vice versa please see learn.microsoft.com/en-us/windows/wsl/… . in your case going back with cd and running with powershell <path>.Flyte
V
3

There are two ways to go about this:

  1. You can change your working directory to that of your shell script and execute it normally. To do so, follow these steps:
  • Mount the relevant drive cd /mnt/c/.
  • Change directories according to the path of the script.
  1. This approach is more of a hack that I use for the sake of convenience. I have created a folder in my Windows storage wherein I store all Ubuntu WSL related files. Say, D:\Ubuntu. To avoid changing the working directory every time you open WSL, you can modify the shell profile file (bashrc, zshrc etc.) to load the relevant directory at the end.
  • i.e., Add cd /mnt/d/Ubuntu/ at the end of your ~/.zshrc file if you use zsh or the relevant profile file otherwise.
Viviyan answered 11/6, 2021 at 14:16 Comment(1)
I really recommend that new users (at least) stay away from the "adding a cd in the startup config` hack. I see too many questions from folks who have done this and it messes with them later.Asquint
Z
15

In WSL2, using the -File option worked for me:

powershell.exe -File path/to/script.ps1
Zadazadack answered 8/10, 2021 at 8:57 Comment(2)
powershell.exe -F ~/win/common/utils/fix_wsl.ps1 gives me an Error saying The argument '/home/user/win/common/utils/fix_wsl.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter.Garibold
Cd to the dir and executing PowerShell with file in current dir works though.Garibold
V
3

There are two ways to go about this:

  1. You can change your working directory to that of your shell script and execute it normally. To do so, follow these steps:
  • Mount the relevant drive cd /mnt/c/.
  • Change directories according to the path of the script.
  1. This approach is more of a hack that I use for the sake of convenience. I have created a folder in my Windows storage wherein I store all Ubuntu WSL related files. Say, D:\Ubuntu. To avoid changing the working directory every time you open WSL, you can modify the shell profile file (bashrc, zshrc etc.) to load the relevant directory at the end.
  • i.e., Add cd /mnt/d/Ubuntu/ at the end of your ~/.zshrc file if you use zsh or the relevant profile file otherwise.
Viviyan answered 11/6, 2021 at 14:16 Comment(1)
I really recommend that new users (at least) stay away from the "adding a cd in the startup config` hack. I see too many questions from folks who have done this and it messes with them later.Asquint
S
3

None of these answers are correct. powershell.exe is a Windows program so expects a Windows path as an argument.

powershell.exe -File C:\\Users\\jason\\Documents\\WindowsPowerShell\\Scripts\\Write-EventLog-1777.ps1

As the backslash character is used for escaping in Linux, you need to escape the backslash with another backslash.

Saundra answered 10/9, 2023 at 10:1 Comment(1)
Only this answer worked to meHesketh
K
2

For me this answer was almost the good one but when running for instance:

powershell.exe -File /mnt/c/path/to/script/script.ps1

I got following error:

The argument '/mnt/c/path/to/script/script.ps1' to the -File parameter does not exist. Provide the path to an existing '.ps1' file as an argument to the -File parameter.

I then have to:

cd /mnt/c/path/to/script
powershell.exe -File script.ps1
Kenon answered 1/7, 2022 at 14:14 Comment(2)
I get this, also. Is there any way to use a full absolute path like this? I don't like having to cd to the directory.Silsby
I did not find any way to call with full absolute path, and I don't like to have to cd too... Moreover when we want to stay in same folder, we have to cd - (or cd - > /dev/null if we don't want to have new path echoed).Kenon
K
1

This worked for me. You need to have installed Powershell in WSL

I have installed Ubuntu WSL, follow this instructions: Installing PowerShell on Ubuntu

Get-WslPath function

Converts Windows path to WSL path.

Examples

Get-WslPath "C:\Users\Megam\.CppLibs"
Get-WslPath "$PSScriptRoot"
Get-WslPath "$PSCommandPath"

Output

/mnt/c/Users/Megam/.CppLibs
/mnt/c/Users/Megam/Desktop/PsScript
/mnt/c/Users/Megam/Desktop/PsScript/MyScript.ps1

Full code. Call same script in WSL.

Calling script from Windows ./testcode.ps1 -Parameter1 10 -Parameter2 "HelloWorld"

[CmdletBinding()]
param (
    [Parameter()]
    [int]
    $Parameter1,

    [Parameter()]
    [string]
    $Parameter2
)

function Get-WslPath {
    param (
        [string]$Path
    )
    if ($Path -match '^([A-Za-z]):[\\\/]') {
        $drive = $matches[1].ToLower()
        $result = "/mnt/$drive" + ($Path -replace '^([A-Za-z]):[\\\/]', '/')
        $result = $result.Replace("\", "/")
        return $result 
    }
    else {
        throw "Invalid path '$Path'."
    }
}

if ($IsWindows) {
    $scriptParameters = @{
        "Script"     = (Get-WslPath -Path "$PSCommandPath")
        "Parameter1" = $Parameter1
        "Parameter2" = $Parameter2
    }
    Write-Host "█ Windows WSL - Code"
    Write-Host "ScriptRoot: $PSScriptRoot"
    Write-Host "CommandPath: $PSCommandPath"
    Write-Warning "Incompatible platform: Windows. Using WSL."
    & wsl pwsh -Command {
        $params = $args[0]
        Write-Host "Wsl User: " -NoNewline ; & whoami
        & "$($params.Script)" -Parameter1 $params.Parameter1 -Parameter2 $params.Parameter2
    } -args $scriptParameters
    exit
}

## WSL, Linux, MacOS code here.
Write-Host "█ Linux WSL - Code"
Write-Host "ScriptRoot: $PSScriptRoot"
Write-Host "CommandPath: $PSCommandPath"
Write-Host "Parameter1: $Parameter1"
Write-Host "Parameter2: $Parameter2"

Output

█ Windows WSL - Code
ScriptRoot: C:\Users\Megam\Desktop
CommandPath: C:\Users\Megam\Desktop\testcode.ps1
WARNING: Incompatible platform: Windows. Using WSL.
Wsl User: x
█ Linux WSL - Code
ScriptRoot: /mnt/c/Users/Megam/Desktop
CommandPath: /mnt/c/Users/Megam/Desktop/testcode.ps1
Parameter1: 10
Parameter2: HelloWorld

output

Koziel answered 4/4 at 21:52 Comment(0)
B
0

Here is the evidence, that with the WSL2, our software can make the Powershell script encrypted and protected: See this picture:

And it can detect and kill the process that uses fanotify because we think it can be used by attackers to hide critical file change (it also can find and kill dtrace/strace/stap/bpftrace/debuggers and process that opens /dev/kmem, /dev/mem, /proc/kcore, and the protected process' /proc/pid/mem etc): This picture shows the encrypted PowerShell script now can detect and kill possible attackers' processes

Blinny answered 27/2, 2022 at 5:52 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Sell

© 2022 - 2024 — McMap. All rights reserved.