iT邦幫忙

2024 iThome 鐵人賽

DAY 4
1

在 Day 2 摘要重點時有講到『 PowerShell 並不是一種指令碼語言,也不是一種程式語言,PowerShell 實際上是一種命令列 shell ( a command-line shell )。 』,因此本書第四章作者要我們學習的重點即是執行命令和使用命令列工具。

關於安全性

在這一小節中,我們的目標是幫助你深入了解 PowerShell 如何對環境中的安全性造成影響,並指導你調整 PowerShell,在安全性與功能性之間達到你所期望的平衡。

遵循目前使用者權限

PowerShell 只能執行你已有權限的操作。換言之,如果你原本可以透過圖形介面新增、修改或刪除某資料夾中的檔案,那麼你也可以透過 PowerShell 執行相同的操作。正如書中所提到:

PowerShell 的安全機制不是為了限制使用者輸入或執行他們已有權限的命令。它的理念是,「欺騙使用者輸入一個冗長又複雜的命令」這件事是困難的,所以 PowerShell 不會去套用任何使用者現有以外的安全策略。

預設的執行原則( execution policy )

PowerShell 的執行政策是一種安全功能,用於控制 PowerShell 加載配置文件和運行腳本的條件,從而有助於防止執行惡意腳本,它規範了 PowerShell 能執行的指令碼,可透過 about_Execution_Policies 了解細節。

> get-help execution

Name                              Category  Module                    Synopsis
----                              --------  ------                    --------
Get-ExecutionPolicy               Cmdlet    Microsoft.PowerShell.Sec… Gets the execution policies for the current session.
Set-ExecutionPolicy               Cmdlet    Microsoft.PowerShell.Sec… Sets the PowerShell execution policies for Windows computers.
about_Execution_Policies          HelpFile

> get-help about_Execution_Policies | more

執行政策的作用

  • 非安全系統:執行政策並不是一個限制用戶行為的安全系統。
    • 用戶可以通過在命令行輸入腳本內容來繞過政策,當他們無法直接運行腳本時。
  • 預防措施:執行政策旨在幫助用戶設置基本規則,防止他們無意中違反這些規則。

針對執行策略的整理

透過 ChatGPT 將 about_Execution_Policies 的內容裡針對 PowerShell 執行政策 及 PowerShell 執行策略範圍 整理如下:

PowerShell 執行政策

執行政策 描述 關鍵點
Restricted Windows 用戶端電腦的預設執行政策。- 允許執行單一命令,但不允許腳本。- 阻止執行所有腳本檔案,包括格式化和配置檔(.ps1xml)、模組腳本檔(.psm1)和 PowerShell 配置檔(.ps1)。 嚴格限制,適合高度安全的環境。- 防止任何腳本執行,確保系統不受未經授權的腳本影響。
AllSigned 允許執行腳本。- 要求所有腳本和配置檔都必須由受信任的發行者簽署,包括您在本機電腦上編寫的腳本。- 在執行尚未被您標記為信任或不信任的發行者的腳本時,會提示您確認。- 風險:可能會執行已簽署但惡意的腳本。 確保所有腳本都是經過簽名的,但需要注意簽名腳本的可信度。- 適合需要執行腳本,但又希望增加安全性的環境。
RemoteSigned Windows 伺服器電腦的預設執行政策。- 允許執行腳本。- 要求從網際網路下載的腳本和配置檔具有受信任發行者的數位簽章,這包括透過電子郵件和即時通訊程式收到的檔案。- 對於在本機撰寫且未從網際網路下載的腳本,不要求數位簽章。- 如果使用 Unblock-File Cmdlet 解除封鎖,未簽名的網際網路腳本也可執行。- 風險:可能會執行非網際網路來源的未簽名腳本和可能惡意的簽名腳本。 在安全性和便利性之間取得平衡。- 適合需要執行本機腳本且偶爾需要執行來自網際網路的受信任腳本的環境。- 需要謹慎處理從網際網路下載的腳本,確保其來源可信。
Unrestricted 非 Windows 電腦的預設執行政策,且無法更改。- 未簽名的腳本可以執行。- 在執行非本機內部網路區域的腳本和配置檔前會發出警告。- 風險:可能會執行惡意腳本。 提供最大程度的靈活性,但安全性較低。- 適合需要自由執行各種腳本的環境,但使用者需自行承擔風險。- 注意:在無法區分 UNC 路徑和網際網路路徑的系統上,使用 UNC 路徑識別的腳本在 RemoteSigned 執行政策下可能無法執行。
Bypass 沒有任何限制,不會封鎖任何內容,且無任何警告或提示。- 設計用於將 PowerShell 腳本內建於較大型的應用程式中,或 PowerShell 作為具有自身安全模型的程式基礎的配置中。 完全不受限制,沒有安全性防護措施。- 適合特定自動化任務或應用程式需要,但一般不建議使用。
Undefined 當前範圍內未設置執行政策。- 如果所有範圍的執行政策都是 Undefined,則有效執行政策為:Windows 用戶端為 Restricted,Windows 伺服器為 RemoteSigned 表示未設置特定的執行政策,系統將使用預設值。- 建議明確設定執行政策以符合安全需求。
Default 設置為預設執行政策。- Windows 用戶端電腦為 Restricted。- Windows 伺服器電腦為 RemoteSigned 快速恢復到系統預設的執行政策。

注意事項

  • 僅在 Windows 平台上強制執行:執行政策僅在 Windows 系統上生效,非 Windows 系統上默認為 Unrestricted,且無法更改。
  • 執行政策的作用範圍:可以在不同的範圍設置執行政策(如本機電腦、當前使用者、特定會話等)。
  • 非安全邊界:執行政策不是為了限制使用者行為的安全系統,而是為了防止無意間執行惡意腳本。
  • 更改執行政策:使用 Get-ExecutionPolicy 查看當前政策,Set-ExecutionPolicy 更改政策(注意:在非 Windows 系統上,Set-ExecutionPolicy 可用但無效)。
  • 風險提示:無論設定何種執行政策,都需謹慎執行腳本,特別是來自未知或不受信任來源的腳本。

PowerShell 執行策略範圍一覽

範圍(Scope) 描述 存儲位置
MachinePolicy 由 群組原則(Group Policy)為計算機上的所有使用者設定。 不存儲在本地,直接由群組原則管理
UserPolicy 由 群組原則 為當前使用者設定。 不存儲在本地,直接由群組原則管理
Process 僅影響當前的 PowerShell 會話。執行策略保存在環境變數 $env:PSExecutionPolicyPreference 中。會話關閉時,該變數和其值會被刪除。 環境變數 $env:PSExecutionPolicyPreference
CurrentUser 執行策略僅影響當前使用者。存儲在註冊表的 HKEY\_CURRENT\_USER 子鍵中。 HKEY\_CURRENT\_USER 註冊表子鍵
LocalMachine 執行策略影響當前計算機上的所有使用者。存儲在註冊表的 HKEY\_LOCAL\_MACHINE 子鍵中。 HKEY\_LOCAL\_MACHINE 註冊表子鍵

注意事項

  • 優先級順序:上述 Scope 的排列順序即為優先級順序,從最高到最低依次是:MachinePolicyUserPolicyProcessCurrentUserLocalMachine
  • 預設值:在設定執行策略時,LocalMachine 是預設的作用域。
  • 優先級影響:在當前會話中,優先級高的策略會覆蓋低優先級策略,即使低優先級策略更為嚴格。

設定 execution policy

透過 help system 直接看範例

> get-help Set-ExecutionPolicy -Examples | more

-------------- Example 1: Set an execution policy --------------

    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
    Get-ExecutionPolicy -List

    Scope ExecutionPolicy
            ----- ---------------
    MachinePolicy       Undefined
       UserPolicy       Undefined
          Process       Undefined
      CurrentUser    RemoteSigned
     LocalMachine    RemoteSigned

    The `Set-ExecutionPolicy` cmdlet uses the ExecutionPolicy parameter to specify the `RemoteSigned` policy. The Scope parameter specifies the default scope value, `LocalMachine`. To view the execution policy settings, use the `Get-ExecutionPolicy` cmdlet with the List parameter.


PowerShell 命令的結構

範例

https://ithelp.ithome.com.tw/upload/images/20240918/20168708cd8WnAFfc6.png

Cmdlet:Get-Command

依循「動詞-名詞」的命名規則,與 Parameter 之間要用空格間隔開來。

Paramater 1

參數都以 - ( dash ) 開頭,Verb 是 Parameter 1 的參數名稱,Get 是 Parameter 1 的參數值,因為參數值內沒有包含空格或標點符號,因此不需要用引號包起來。

Paramater 2

Module 是 Parameter 2 的參數名稱,並被賦予了兩個值:PSReadLine 以及 PowerShellGet,兩者之間以逗號隔開。

Paramater 3

Syntax 是開關型參數( switch parameter ),不需要賦值。

get-help get-command -parameter * | grep -A 17 -B 1 Syntax

-Syntax <System.Management.Automation.SwitchParameter>
    Indicates that this cmdlet gets only the following specified data about the command:

    - Aliases. Gets the standard name.

    - Cmdlets. Gets the syntax.

    - Functions and filters. Gets the function definition.

    - Scripts and applications or files. Gets the path and filename.

    Required?                    false
    Position?                    named
    Default value                False
    Accept pipeline input?       True (ByPropertyName)
    Accept wildcard characters?  false

其他規則

  • 所有內容都不區分大小寫。
  • 參數名稱前面的 dash 與參數本身沒有空格。

別名( Alias )

PowerShell 別名基本上就是命令的暱稱( nickname ),可以透過 Get-Alias 去搜尋 cmdlet 的別名。
此外,PowerShell 的別名與「 Bash 中的別名 」略有不同,別名可以是一個帶有多個參數的命令捷徑,但是 PowerShell 的別名就只是命令名稱的暱稱。

> Get-Alias -Definition "Get-Process"

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           gps -> Get-Process

外部命令的支援

命令分類

主要分類以下幾種類型

Cmdlet

PowerShell 原生的內部命令,多半依循「動詞-名詞」的命名規則。

Function

由 PowerShell 定義的函數,可能是使用者自定義,或是由模組提供的。

Alias

對現有命令的簡化名稱,方便輸入

Application

外部命令,通常是系統中的可執行檔案( .exe, .bat 等 )

如何確認命令的類型

透過 Get-Command

Get-Command ping

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     ping                                               0.0.0.0    /sbin/ping

PS /Users/kanglin/code/stackcore_repo> Get-Command nslookup

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     nslookup                                           0.0.0.0    /usr/bin/nslookup

PS /Users/kanglin/code/stackcore_repo> Get-Command dig

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     dig                                                0.0.0.0    /usr/bin/dig

PS /Users/kanglin/code/stackcore_repo> Get-Command get-item

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Get-Item                                           7.0.0.0    Microsoft.PowerShell.Management

外部命令的問題

書中提到,並不是所有的外部命令都能在 PowerShell 中順利運行,這是因為 PowerShell 的解析器( parser )有時候無法正確地解讀,而當一個外部命令有很多參數時,事情可能變得複雜,而這也是最容易看到 PowerShell 出錯的地方,針對這問題,書中也提供了一段確保命令參數能正確執行的方法:

方法一

透過將外部命令全部用變數方式儲存參數值後,透過 & (呼叫運算子)告訴 PowerShell 執行後面的命令或腳本,無論是名稱是否符合 PowerShell 的命名規則。

$exe = "func"
$action = "new"
$language = "powershell"
$template = "HttpTrigger"
$name = "myFunc"
& $exe $action -l $language -t $template -n $name

方法二

在 PowerShell v3 以上的版本,可以在參數前加上兩個 dash 以及一個百分比符號,PowerShell 就不會試圖去解析接下來的變數值內容。
--% 一旦使用後,PowerShell 會對其後的所有內容停止解析,包括變數展開、參數解析等。
Refer - 停止剖析令牌

$name = "MyFunctionApp"
func azure functionapp list-functions --% $name

明日主題

Day 5 - 使用 Provider


上一篇
Day 3 - 使用說明系統
下一篇
Day 5 - 使用 Provider
系列文
《30天挑戰精通 PowerShell:從 Windows Server 到 Azure DevOps 自動化之旅》30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言