Cách chuyển các giá trị boolean sang tập lệnh PowerShell từ dấu nhắc lệnh


103

Tôi phải gọi một tập lệnh PowerShell từ một tệp hàng loạt. Một trong những đối số của tập lệnh là giá trị boolean:

C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -File .\RunScript.ps1 -Turn 1 -Unify $false

Lệnh không thành công với lỗi sau:

Cannot process argument transformation on parameter 'Unify'. Cannot convert value "System.String" to type "System.Boolean", parameters of this type only accept booleans or numbers, use $true, $false, 1 or 0 instead.

At line:0 char:1
+  <<<< <br/>
+ CategoryInfo          : InvalidData: (:) [RunScript.ps1], ParentContainsErrorRecordException <br/>
+ FullyQualifiedErrorId : ParameterArgumentTransformationError,RunScript.ps1

Hiện tại, tôi đang sử dụng một chuỗi để chuyển đổi boolean bên trong tập lệnh của mình. Nhưng làm cách nào để chuyển các đối số boolean sang PowerShell?

Câu trả lời:


57

Có vẻ như powershell.exe không đánh giá đầy đủ các đối số tập lệnh khi -Filetham số được sử dụng. Cụ thể, $falseđối số đang được coi là một giá trị chuỗi, theo cách tương tự như ví dụ bên dưới:

PS> function f( [bool]$b ) { $b }; f -b '$false'
f : Cannot process argument transformation on parameter 'b'. Cannot convert value 
"System.String" to type "System.Boolean", parameters of this type only accept 
booleans or numbers, use $true, $false, 1 or 0 instead.
At line:1 char:36
+ function f( [bool]$b ) { $b }; f -b <<<<  '$false'
    + CategoryInfo          : InvalidData: (:) [f], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,f

Thay vì sử dụng, -Filebạn có thể thử -Command, điều này sẽ đánh giá cuộc gọi dưới dạng tập lệnh:

CMD> powershell.exe -NoProfile -Command .\RunScript.ps1 -Turn 1 -Unify $false
Turn: 1
Unify: False

Như David gợi ý, việc sử dụng đối số switch cũng sẽ dễ hiểu hơn, đơn giản hóa lệnh gọi bằng cách loại bỏ nhu cầu truyền giá trị boolean một cách rõ ràng:

CMD> powershell.exe -NoProfile -File .\RunScript.ps1 -Turn 1 -Unify
Turn: 1
Unify: True

6
Đối với những người (như tôi) phải giữ tham số "-File" và không thể thay đổi thành đối số switch, nhưng có quyền kiểm soát các giá trị chuỗi được gửi, thì giải pháp đơn giản nhất là chuyển đổi tham số thành a boolean using [System.Convert] :: ToBoolean ($ Unify); các giá trị chuỗi sau đó phải là "Đúng" hoặc "Sai".
Chris Haines

187

Cách sử dụng rõ ràng hơn có thể là sử dụng các thông số chuyển đổi thay thế. Sau đó, chỉ cần sự tồn tại của tham số Unify có nghĩa là nó đã được thiết lập.

Như vậy:

param (
  [int] $Turn,
  [switch] $Unify
)

21
Đây phải là câu trả lời được chấp nhận. Để thảo luận thêm, bạn có thể đặt giá trị mặc định giống như bất kỳ thông số nào khác như sau:[switch] $Unify = $false
Mario Tacke

Tôi đã bỏ qua câu trả lời này, vì tôi chắc chắn rằng Boolean là con đường để đi. Không phải vậy. Switch đóng gói chức năng của boolean và dừng các loại lỗi sau: "Không thể chuyển đổi giá trị" False "thành loại" System.Management.Automation.ParameterAttribute ". Công tắc đã hoạt động với tôi.
TinyRacoon

2
@MarioTacke Nếu bạn không chỉ định tham số switch khi gọi tập lệnh thì nó sẽ tự động được đặt thành $false. Vì vậy, không cần đặt giá trị mặc định một cách rõ ràng.
doubleDown

Đề xuất này hoạt động rất tốt; đã có thể cập nhật một trong các tham số từ [bool] thành [switch] và điều này cho phép tôi chuyển thành công đối số qua Task Scheduler.
JustaDaKaje

12

Đây là một câu hỏi cũ hơn, nhưng thực sự có câu trả lời cho điều này trong tài liệu PowerShell. Tôi đã gặp vấn đề tương tự và RTFM đã thực sự giải quyết nó một lần. Hầu hết.

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_powershell_exe

Tài liệu cho tham số -File cho biết rằng "Trong một số trường hợp hiếm hoi, bạn có thể cần cung cấp giá trị Boolean cho tham số switch. Để cung cấp giá trị Boolean cho tham số switch trong giá trị của tham số File, hãy đặt tên tham số và giá trị trong dấu ngoặc nhọn, chẳng hạn như sau: -File. \ Get-Script.ps1 {-All: $ False} "

Tôi đã phải viết nó như thế này:

PowerShell.Exe -File MyFile.ps1 {-SomeBoolParameter:False}

Vì vậy, không có '$' trước câu lệnh true / false và điều đó phù hợp với tôi, trên PowerShell 4.0


1
Cảm ơn bạn đã chia sẻ! Đã giải quyết vấn đề của tôi một cách hoàn hảo.
Julia Schwarz,

1
Liên kết trong câu trả lời dường như đã bị thay đổi nội dung. Tuy nhiên, tôi tìm thấy câu trả lời ở đây
Slogmeister Extraordinaire

Liên kết tài liệu hiện tại about_powershell.exe chỉ rung powershell -h.
Seth

Tôi ngạc nhiên rằng cách giải quyết khó xử này từng hoạt động - nó không có trong Windows PowerShell v5.1 (không có cũng không có hàng đầu $); cũng lưu ý rằng nó không còn cần thiết trong PowerShell Core . Tôi đã yêu cầu chỉnh sửa tài liệu; xem github.com/MicrosoftDocs/PowerShell-Docs/issues/4964
mklement0

11

Hãy thử đặt loại thông số của bạn thành [bool]:

param
(
    [int]$Turn = 0
    [bool]$Unity = $false
)

switch ($Unity)
{
    $true { "That was true."; break }
    default { "Whatever it was, it wasn't true."; break }
}

Ví dụ này được mặc định $Unity$falsenếu không có đầu vào nào được cung cấp.

Sử dụng

.\RunScript.ps1 -Turn 1 -Unity $false

1
Câu trả lời của Emperor XLII và nhận xét của bạn về nó liên quan đến -Filetham số sẽ bao gồm mọi khía cạnh của câu hỏi ban đầu. Tôi sẽ để lại câu trả lời của mình vì ai đó cũng có thể thấy gợi ý của tôi về việc cung cấp một giá trị mặc định hữu ích.
Filburt

Làm tốt lắm Filburt. Câu trả lời của bạn khiến tôi phải kiểm tra tập lệnh của mình, tập lệnh đã được chỉ định mặc định là giá trị bắt buộc $ false (tôi đã viết điều đó vài năm trước và đã quên tất cả về nó) - vì vậy tôi thậm chí không phải chỉ định tham số boolean có vấn đề trên dòng lệnh bây giờ. Tuyệt vời :)
Zeek2

5

Tôi nghĩ, cách tốt nhất để sử dụng / đặt giá trị boolean làm tham số là sử dụng trong tập lệnh PS của bạn như sau:

Param(
    [Parameter(Mandatory=$false)][ValidateSet("true", "false")][string]$deployApp="false"   
)

$deployAppBool = $false
switch($deployPmCmParse.ToLower()) {
    "true" { $deployAppBool = $true }
    default { $deployAppBool = $false }
}

Vì vậy, bây giờ bạn có thể sử dụng nó như sau:

.\myApp.ps1 -deployAppBool True
.\myApp.ps1 -deployAppBool TRUE
.\myApp.ps1 -deployAppBool true
.\myApp.ps1 -deployAppBool "true"
.\myApp.ps1 -deployAppBool false
#and etc...

Vì vậy, trong các đối số từ cmd, bạn có thể chuyển giá trị boolean dưới dạng chuỗi đơn giản :).


2

Trong PowerShell, các tham số boolean có thể được khai báo bằng cách đề cập đến kiểu của chúng trước biến của chúng.

    function GetWeb() {
             param([bool] $includeTags)
    ........
    ........
    }

Bạn có thể gán giá trị bằng cách chuyển $ true | $ false

    GetWeb -includeTags $true

Chỉ cần truyền các đối số đầu vào được đặt tên một cách rõ ràng như vậy đã có tác dụng. Cảm ơn Ahmed
Steve Taylor

0

Để tóm tắt và bổ sung cho các câu trả lời hiện có , kể từ Windows PowerShell v5.1 / PowerShell Core 7.0.0-preview.4:

Câu trả lời của David Mohundro đã chỉ ra một cách chính xác rằng thay vì các [bool]tham số, bạn nên sử dụng [switch]các tham số trong PowerShell , trong đó sự hiện diện so với không có tên công tắc ( -Unifyđược chỉ định so với không được chỉ định) ngụ ý giá trị của nó , điều này làm cho vấn đề ban đầu biến mất.


Tuy nhiên, đôi khi bạn vẫn có thể cần phải chuyển giá trị chuyển đổi một cách rõ ràng , đặc biệt nếu bạn đang xây dựng một dòng lệnh theo chương trình :


Trong PowerShell Core , sự cố ban đầu (được mô tả trong câu trả lời của Emperor XLII ) đã được khắc phục .

Nghĩa là, để truyền $truerõ ràng cho một [switch]tham số có tên, -Unifybây giờ bạn có thể viết:

pwsh -File .\RunScript.ps1 -Unify:$true  # !! ":" separates name and value, no space

Các giá trị sau đây có thể được sử dụng: $false, false, $true, true, nhưng lưu ý rằng đi qua 0hay 1không không làm việc.

Lưu ý cách tên chuyển đổi được phân tách khỏi giá trị bằng :và không được có khoảng trắng giữa hai.

Lưu ý: Nếu bạn khai báo một [bool]tham số thay vì một [switch](mà bạn thường không nên), bạn phải sử dụng cùng một cú pháp; mặc dù -Unify $false sẽ hoạt động nhưng hiện tại thì không - hãy xem vấn đề GitHub này .


Trong Windows PowerShell , sự cố ban đầu vẫn tiếp diễn và - do Windows PowerShell không còn được phát triển tích cực - khó có thể được khắc phục.

  • Cách giải quyết được đề xuất trong câu trả lời của LarsWA - mặc dù nó dựa trên chủ đề trợ giúp chính thức của bài viết này - không hoạt động trong v5.1

    • Sự cố GitHub này yêu cầu sửa tài liệu và cũng cung cấp một lệnh kiểm tra cho thấy cách giải quyết không hiệu quả.
  • Sử dụng -Commandthay vì -Filelà cách giải quyết hiệu quả duy nhất :

:: # From cmd.exe
powershell -Command "& .\RunScript.ps1 -Unify:$true" 

Với việc -Commandbạn đang chuyển một cách hiệu quả một đoạn mã PowerShell , này sau đó được đánh giá như bình thường - và bên trong PowerShell truyền $true$falsehoạt động (nhưng không truefalsenhư bây giờ cũng được chấp nhận với-File ).

Lưu ý :

  • Việc sử dụng -Commandcó thể dẫn đến việc giải thích bổ sung các đối số của bạn, chẳng hạn như nếu chúng chứa $ký tự. (với -File, đối số là nghĩa đen ).

  • Sử dụng -Commandcó thể dẫn đến một mã thoát khác .

Để biết chi tiết, hãy xem câu trả lời nàycâu trả lời này .


0

Tôi đã có một cái gì đó tương tự khi truyền một tập lệnh cho một hàm với lệnh gọi. Tôi đã chạy lệnh trong dấu ngoặc kép thay vì dấu ngoặc kép, vì sau đó nó trở thành một chuỗi ký tự.'Set-Mailbox $sourceUser -LitigationHoldEnabled $false -ElcProcessingDisabled $true';


0

Chạy các tập lệnh powershell trên linux từ bash cũng cho vấn đề tương tự. Giải quyết nó gần giống như câu trả lời của LarsWA:

Đang làm việc:

pwsh -f ./test.ps1 -bool:true

Không làm việc:

pwsh -f ./test.ps1 -bool=1
pwsh -f ./test.ps1 -bool=true
pwsh -f ./test.ps1 -bool true
pwsh -f ./test.ps1 {-bool=true}
pwsh -f ./test.ps1 -bool=$true
pwsh -f ./test.ps1 -bool=\$true
pwsh -f ./test.ps1 -bool 1
pwsh -f ./test.ps1 -bool:1

-3

Bạn cũng có thể sử dụng 0cho Falsehoặc 1cho True. Nó thực sự gợi ý rằng trong thông báo lỗi:

Không thể xử lý chuyển đổi đối số trên tham số 'Unify'. Không thể chuyển đổi giá trị "System.String"để loại "System.Boolean", các thông số của loại này chỉ chấp nhận các phép toán luận hoặc số, sử dụng $true, $false, 1 hoặc 0 để thay thế.

Để biết thêm thông tin, hãy xem bài viết MSDN này về Giá trị và toán tử Boolean .


10
Điều đó không hoạt động. Nó đang mong đợi số nguyên 1 hoặc 0, nhưng việc chuyển nó qua sẽ -Filediễn giải nó thành chuỗi, do đó không thành công với cùng một lỗi.
Erti-Chris Eelmaa

Câu trả lời này là sai, là gợi ý không làm việc
MJS
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.