Catatan: PowerShell 1.0
Saya ingin mendapatkan nama file PowerShell yang sedang dijalankan. Artinya, jika saya memulai sesi saya seperti ini:
powershell.exe .\myfile.ps1
Saya ingin mendapatkan string ". \ Myfile.ps1" (atau sesuatu seperti itu). EDIT : "myfile.ps1" lebih disukai.
Ada ide?
powershell
Ron Klein
sumber
sumber
Jawaban:
Saya telah mencoba meringkas berbagai jawaban di sini, diperbarui untuk PowerShell 5:
Jika Anda hanya menggunakan PowerShell 3 atau lebih tinggi, gunakan
$PSCommandPath
Jika ingin kompatibilitas dengan versi yang lebih lama, masukkan shim:
if ($PSCommandPath -eq $null) { function GetPSCommandPath() { return $MyInvocation.PSCommandPath; } $PSCommandPath = GetPSCommandPath; }
Ini menambahkan
$PSCommandPath
jika belum ada.Kode shim dapat dieksekusi di mana saja (tingkat atas atau di dalam fungsi), meskipun
$PSCommandPath
variabel tunduk pada aturan pelingkupan normal (misalnya, jika Anda meletakkan shim dalam suatu fungsi, variabel tersebut dibatasi hanya untuk fungsi itu).Detail
Ada 4 metode berbeda yang digunakan dalam berbagai jawaban, jadi saya menulis skrip ini untuk menunjukkan masing-masing (plus
$PSCommandPath
):function PSCommandPath() { return $PSCommandPath; } function ScriptName() { return $MyInvocation.ScriptName; } function MyCommandName() { return $MyInvocation.MyCommand.Name; } function MyCommandDefinition() { # Begin of MyCommandDefinition() # Note: ouput of this script shows the contents of this function, not the execution result return $MyInvocation.MyCommand.Definition; # End of MyCommandDefinition() } function MyInvocationPSCommandPath() { return $MyInvocation.PSCommandPath; } Write-Host ""; Write-Host "PSVersion: $($PSVersionTable.PSVersion)"; Write-Host ""; Write-Host "`$PSCommandPath:"; Write-Host " * Direct: $PSCommandPath"; Write-Host " * Function: $(ScriptName)"; Write-Host ""; Write-Host "`$MyInvocation.ScriptName:"; Write-Host " * Direct: $($MyInvocation.ScriptName)"; Write-Host " * Function: $(ScriptName)"; Write-Host ""; Write-Host "`$MyInvocation.MyCommand.Name:"; Write-Host " * Direct: $($MyInvocation.MyCommand.Name)"; Write-Host " * Function: $(MyCommandName)"; Write-Host ""; Write-Host "`$MyInvocation.MyCommand.Definition:"; Write-Host " * Direct: $($MyInvocation.MyCommand.Definition)"; Write-Host " * Function: $(MyCommandDefinition)"; Write-Host ""; Write-Host "`$MyInvocation.PSCommandPath:"; Write-Host " * Direct: $($MyInvocation.PSCommandPath)"; Write-Host " * Function: $(MyInvocationPSCommandPath)"; Write-Host "";
Keluaran:
PS C:\> .\Test\test.ps1 PSVersion: 5.1.19035.1 $PSCommandPath: * Direct: C:\Test\test.ps1 * Function: C:\Test\test.ps1 $MyInvocation.ScriptName: * Direct: * Function: C:\Test\test.ps1 $MyInvocation.MyCommand.Name: * Direct: test.ps1 * Function: MyCommandName $MyInvocation.MyCommand.Definition: * Direct: C:\Test\test.ps1 * Function: # Begin of MyCommandDefinition() # Note this is the contents of the MyCommandDefinition() function, not the execution results return $MyInvocation.MyCommand.Definition; # End of MyCommandDefinition() $MyInvocation.PSCommandPath: * Direct: * Function: C:\Test\test.ps1
Catatan:
C:\
, tetapi skrip sebenarnya adalahC:\Test\test.ps1
..\Test\test.ps1
)$PSCommandPath
adalah satu-satunya cara yang dapat diandalkan, tetapi diperkenalkan di PowerShell 3sumber
$PSCommandPath
jika warisan (WindowsXP) tidak diperlukan.function PSCommandPath
) dan referensi ke fungsi yang salah (Write-Host " * Direct: $PSCommandPath"; Write-Host " * Function: $(ScriptName)";
- atau apakah saya mengabaikan sesuatu yang jelas?Meskipun Jawaban saat ini benar dalam banyak kasus, ada situasi tertentu yang tidak akan memberikan jawaban yang benar. Jika Anda menggunakan di dalam fungsi skrip Anda maka:
$MyInvocation.MyCommand.Name
Mengembalikan nama fungsi, bukan nama nama skrip.
function test { $MyInvocation.MyCommand.Name }
Akan memberi Anda " tes " tidak peduli bagaimana skrip Anda dinamai. Perintah yang tepat untuk mendapatkan nama skrip selalu
$MyInvocation.ScriptName
ini mengembalikan jalur lengkap dari skrip yang Anda jalankan. Jika Anda hanya membutuhkan nama file skrip daripada kode ini akan membantu Anda:
split-path $MyInvocation.PSCommandPath -Leaf
sumber
$MyInvocation.ScriptName
kembalikan string kosong untuk saya, PS v3.0.$MyInvocation.ScriptName
hanya bekerja dari dalam suatu fungsi. Lihat jawaban saya di bawah .Jika Anda hanya ingin nama file (bukan path lengkap) gunakan ini:
$ScriptName = $MyInvocation.MyCommand.Name
sumber
Coba berikut ini
$path = $MyInvocation.MyCommand.Definition
Ini mungkin tidak memberi Anda jalur sebenarnya yang diketik, tetapi ini akan memberi Anda jalur yang valid ke file.
sumber
$path = Split-Path $MyInvocation.MyCommand.Definition -Parent
Jika Anda mencari direktori saat ini tempat skrip dijalankan, Anda dapat mencoba yang ini:
$fullPathIncFileName = $MyInvocation.MyCommand.Definition $currentScriptName = $MyInvocation.MyCommand.Name $currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "") Write-Host $currentExecutingPath
sumber
C:\ilike.ps123\ke.ps1
, bukan?Replace()
metode ini menggantikan setiap kemunculan jarum (bukan hanya kejadian terakhir) dan saya juga mengujinya. Namun, sebaiknya lakukan sesuatu seperti pengurangan string.String.TrimEnd()
($currentExecutingPath = $fullPathIncFileName.TrimEnd($currentScriptName)
)? - Ini bekerja dengan benar:"Ich bin Hamster".TrimEnd("ster")
kembaliIch bin Ham
dan"Ich bin Hamsterchen".TrimEnd("ster")
kembaliIch bin Hamsterchen
(bukanIch bin Hamchen
) - Baik!$currentScriptPath = $MyInvocation.MyCommand.Definition; $currentScriptName = $MyInvocation.MyCommand.Name; $currentScriptDir = $currentScriptPath.Substring(0,$currentScriptPath.IndexOf($currentScriptName));
berhati-hatilah: Tidak seperti variabel
$PSScriptRoot
dan$PSCommandPath
otomatis, propertiPSScriptRoot
danPSCommandPath
dari$MyInvocation
variabel otomatis berisi informasi tentang pemanggil atau skrip pemanggil, bukan skrip saat ini.misalnya
... di mana
DPM.ps1
berisiWrite-Host ("="+($MyInvocation.PSCommandPath)+"!"+$PSCommandPath)
sumber
Saya berpendapat bahwa ada metode yang lebih baik, dengan menetapkan cakupan variabel $ MyInvocation.MyCommand.Path:
contoh> $ script : MyInvocation.MyCommand.Name
Metode ini berfungsi di semua situasi pemanggilan:
EX: Somescript.ps1
function printme () { "In function:" ( "MyInvocation.ScriptName: " + [string]($MyInvocation.ScriptName) ) ( "script:MyInvocation.MyCommand.Name: " + [string]($script:MyInvocation.MyCommand.Name) ) ( "MyInvocation.MyCommand.Name: " + [string]($MyInvocation.MyCommand.Name) ) } "Main:" ( "MyInvocation.ScriptName: " + [string]($MyInvocation.ScriptName) ) ( "script:MyInvocation.MyCommand.Name: " + [string]($script:MyInvocation.MyCommand.Name) ) ( "MyInvocation.MyCommand.Name: " + [string]($MyInvocation.MyCommand.Name) ) " " printme exit
KELUARAN:
PS> powershell C:\temp\test.ps1 Main: MyInvocation.ScriptName: script:MyInvocation.MyCommand.Name: test.ps1 MyInvocation.MyCommand.Name: test.ps1 In function: MyInvocation.ScriptName: C:\temp\test.ps1 script:MyInvocation.MyCommand.Name: test.ps1 MyInvocation.MyCommand.Name: printme
Perhatikan bagaimana jawaban yang diterima di atas TIDAK mengembalikan nilai saat dipanggil dari Utama. Juga, perhatikan bahwa jawaban yang diterima di atas mengembalikan jalur lengkap ketika pertanyaan meminta nama skrip saja. Variabel cakupan berfungsi di semua tempat.
Juga, jika Anda memang menginginkan jalur lengkap, Anda cukup memanggil:
$script:MyInvocation.MyCommand.Path
sumber
Seperti disebutkan dalam tanggapan sebelumnya, menggunakan "$ MyInvocation" tunduk pada masalah cakupan dan tidak selalu memberikan data yang konsisten (nilai hasil vs. nilai akses langsung). Saya telah menemukan bahwa metode "terbersih" (paling konsisten) untuk mendapatkan info skrip seperti jalur skrip, nama, parms, baris perintah, dll. Apa pun cakupannya (dalam pemanggilan fungsi utama atau berikutnya / bersarang) adalah dengan menggunakan "Get- Variabel "di" MyInvocation "...
# Get the MyInvocation variable at script level # Can be done anywhere within a script $ScriptInvocation = (Get-Variable MyInvocation -Scope Script).Value # Get the full path to the script $ScriptPath = $ScriptInvocation.MyCommand.Path # Get the directory of the script $ScriptDirectory = Split-Path $ScriptPath # Get the script name # Yes, could get via Split-Path, but this is "simpler" since this is the default return value $ScriptName = $ScriptInvocation.MyCommand.Name # Get the invocation path (relative to $PWD) # @GregMac, this addresses your second point $InvocationPath = ScriptInvocation.InvocationName
Jadi, Anda bisa mendapatkan info yang sama dengan $ PSCommandPath, tetapi lebih banyak lagi dalam kesepakatan itu. Tidak yakin, tapi sepertinya "Get-Variable" tidak tersedia sampai PS3 jadi tidak banyak bantuan untuk sistem yang benar-benar tua (tidak diperbarui).
Ada juga beberapa aspek menarik saat menggunakan "-Scope" karena Anda dapat mundur untuk mendapatkan nama, dll. Dari fungsi pemanggil. 0 = saat ini, 1 = orang tua, dll.
Semoga ini bisa membantu.
Ref, https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-variable
sumber
Melakukan beberapa pengujian dengan script berikut, baik pada PS 2 maupun PS 4 dan mendapatkan hasil yang sama. Saya harap ini membantu orang.
$PSVersionTable.PSVersion function PSscript { $PSscript = Get-Item $MyInvocation.ScriptName Return $PSscript } "" $PSscript = PSscript $PSscript.FullName $PSscript.Name $PSscript.BaseName $PSscript.Extension $PSscript.DirectoryName "" $PSscript = Get-Item $MyInvocation.InvocationName $PSscript.FullName $PSscript.Name $PSscript.BaseName $PSscript.Extension $PSscript.DirectoryName
Hasil -
sumber
Ini dapat berfungsi pada sebagian besar versi PowerShell:
(& { $MyInvocation.ScriptName; })
Ini dapat berfungsi untuk Pekerjaan Terjadwal
Get-ScheduledJob |? Name -Match 'JOBNAMETAG' |% Command
sumber