See the below script that I have for renaming Movie files with .mp4 or .mkv extensions:
<# ::
@echo off
powershell -c "iex ((Get-Content -LiteralPath '%~f0') -join [Environment]::Newline); iex 'main %*'"
pause && goto :eof
#>
$path = Split-Path -Path $PSScriptRoot -Parent
echo $path
## $validExtensions = '.mkv', '.mp4'
## Get-ChildItem -LiteralPath $path -File |
## Where-Object Extension -In $validExtensions |
## Where-Object Length -GT 500mb |
## Rename-Item -NewName {
## ($_.BaseName -replace 'MkvHub.com - ' -replace '(?<=1080p|720p).+' -replace '\.', ' ').ToUpper() + $_.Extension
## }
Currently I have commented out the rest of the Powershell code for obvious reason of testing whether the code Split-Path -Path $PSScriptRoot -Parent or split-path $myInvocation.myCommand.path would give us the literal path of this same script during execution or not.
Clearly it doesn't give me the expected path, and instead throws this error:
Split-Path : Cannot bind argument to parameter 'Path' because it is an empty string.
At line:7 char:26
+ $path = Split-Path -Path $PSScriptRoot -Parent
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Split-Path], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.Spli
tPathCommand
Press any key to continue . . .
Also the similar error with split-path $myInvocation.myCommand.path too.
As aforementioned I already tried both split-path $myInvocation.myCommand.path and Split-Path -Path $PSScriptRoot -Parent, but none of them are working.
Can anyone help figuring this out ? I have to make this work in hybrid script only...
Fundamentally, the automatic
$PSScriptRootand$PSCommandPathare only defined inside script files (*.ps1) (and script module files (*.psm1)).Since your hybrid batch-file approach relies on invoking
powershell.exe, the Windows PowerShell CLI, by directly passing source code to its-c(-Command) parameter, these variables are therefore not defined.As Mofi suggests, you can set a variable with the batch file's own directory before calling
powershell.exe, which - due tocmd.exevariables also being environment variables - the PowerShell code can then access as such, using the$env:namespace.However, a robust hybrid batch/PowerShell solution requires the use of the
-FilePowerShell CLI parameter in order to correctly handle pass-through arguments, which in turn requires creating a temporary copy of the batch file as a.ps1file.See this answer, which combines the
-Fileapproach with passing the original batch-file path via an environment variable, allowing the PowerShell code to infer the equivalents of$PSScriptRootand$PSCommandPath.