Membuat alias secara dinamis di PowerShell


3

Saya ingin membuat beberapa alias secara dinamis tetapi saya tidak dapat membuat kode saya berfungsi. Ini kodenya:

# Drives
$drives = ("a","b","c","d","e")
foreach ($drive in $drives) {
    New-Item -Path alias:\ -Name $drive -Value GoToDrive($drive) #.GetNewClosure()
}

function GoToDrive($drive) {
    $formatted = "$($drive):\"
    if (Test-Path $formatted) {
        Set-Location $formatted
    } else {
        Write-Host "`"$formatted`" does not exist."
    }
}

Ketika saya mengetik "a", atau "b", atau salah satu huruf dalam $ drive, itu harus mengubah direktori kerja saya ke huruf drive itu (misalnya: A :).

Kesalahan yang saya dapatkan sekarang adalah ini:

New-Item : A positional parameter cannot be found that accepts argument 'a'.
At C:\Users\prubi\OneDrive\Documentos\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:17 char:5
+     New-Item -Path alias:\ -Name $drive -Value GoToDrive($drive) #.Ge ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-Item], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewItemCommand

New-Item : A positional parameter cannot be found that accepts argument 'b'.
At C:\Users\prubi\OneDrive\Documentos\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:17 char:5
+     New-Item -Path alias:\ -Name $drive -Value GoToDrive($drive) #.Ge ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-Item], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewItemCommand

New-Item : A positional parameter cannot be found that accepts argument 'c'.
At C:\Users\prubi\OneDrive\Documentos\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:17 char:5
+     New-Item -Path alias:\ -Name $drive -Value GoToDrive($drive) #.Ge ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-Item], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewItemCommand

New-Item : A positional parameter cannot be found that accepts argument 'd'.
At C:\Users\prubi\OneDrive\Documentos\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:17 char:5
+     New-Item -Path alias:\ -Name $drive -Value GoToDrive($drive) #.Ge ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-Item], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewItemCommand

New-Item : A positional parameter cannot be found that accepts argument 'e'.
At C:\Users\prubi\OneDrive\Documentos\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:17 char:5
+     New-Item -Path alias:\ -Name $drive -Value GoToDrive($drive) #.Ge ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [New-Item], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewItemCommand

Adakah yang bisa membantu saya menyelesaikan pekerjaan ini?

Jawaban:


3

Masalah langsungnya adalah bahwa PowerShell menafsirkan -Value GoToDrive($drive)sebagai menentukan saklar -Value 'GoToDrive'dan juga parameter posisi $drive. (Ini aneh dan tidak intuitif, ya.) Menutup GoToDrive($drive)tanda kurung akan mencoba untuk memanggil fungsi as-yet-nonexistent GoToDrivedan kemudian menggunakan hasilnya sebagai argumen untuk -Value, yang bukan apa yang Anda cari walaupun GoToDrivetelah didefinisikan sebelumnya. Masalah lain adalah alias tidak bisa memberikan argumen ke perintah yang mereka panggil; mereka hanya nama alternatif untuk perintah.

Anda perlu secara dinamis menjalankan perintah yang membuat fungsi pintasan:

# This is the exact same GoToDrive function you've been using
function GoToDrive($drive) {
    $formatted = "$($drive):\"
    if (Test-Path $formatted) {
        Set-Location $formatted
    } else {
        Write-Host "`"$formatted`" does not exist."
    }
}

# This does the magic
'a', 'b', 'c', 'd', 'e' | % {iex "function $_ {GoToDrive '$_'}"}

Invoke-Expression, atau iexsingkatnya, jalankan argumen yang ditentukan saat runtime seolah-olah Anda sendiri yang mengetiknya di baris perintah. Sehingga baris terakhir dieksekusi function a {GoToDrive 'a'}, lalu function b {GoToDrive 'b'}, dan seterusnya.


Terima kasih banyak atas klarifikasi dan kode kerjanya! Saya menerima jawaban Anda sebagai jawaban yang tepat.
prubini87
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.