PowerShell: Переменная не подставляет значение в строку

Для удобства создания нового правила firewall (брандмауэра Windows) написал такой скрипт:

function AllowOutbound
{
  param( [string]$name, [string]$path, [string]$protocol, [string]$port)
  Write-Output "[+]: '$name' ($path) -> ${protocol}:$port"
  New-NetFirewallRule -DisplayName '$name' -Description '$path' -Program '$path' -Direction Outbound -Group 'USER' -Protocol '$protocol' -RemotePort '$port' 
}

После этого пытаюсь его запустить, но получаю ошибку:

AllowOutbound "Notepad" "%windir%\system32\notepad.exe" "TCP" "443"
[+]: 'Notepad' (%windir%\system32\notepad.exe) -> TCP:443
New-NetFirewallRule : The protocol is invalid.
At C:\Users\Denis\Downloads\func.ps1:10 char:3
+ New-NetFirewallRule -DisplayName '$name' -Description '$path' -Prog ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (MSFT_NetFirewallRule:root/standardcimv2/MSFT_NetFirewallRule) [New-NetFirewallRule], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070057,New-NetFirewallRule

Как видно, в скрипт корректно передались параметры (строчка со знаком плюс [+], но cmdlet New-NetFirewallRule их не стал извлекать, а оставил в виде переменных.

На сетевое правило для notepad.exe внимания не обращайте — это просто для тестирования :)

 

Выяснилось, что проблема была в кавычках!

expressions in single-quoted strings are not evaluated. They are interpreted as literals

 

То есть, если строка находится внутри двойных кавычек, то переменные внутри неё работают. Если в одинарных, то переменные представляются как обычный текст.
Поэтому данный скрипт нужно было переписать так, чтобы вместо одинарных кавычек были двойные:

function AllowOutbound
{
  param( [string]$name, [string]$path, [string]$protocol, [string]$port)
  Write-Output "[+]: '$name' ($path) -> ${protocol}:$port"
  New-NetFirewallRule -DisplayName "$name" -Description "$path" -Program "$path" -Direction Outbound -Group 'USER' -Protocol "$protocol" -RemotePort "$port" }

Кроме этого выяснилось, что cmdlet анализирует путь, поэтому если указать путь к файлу без кавычек, то правило будет создано корректно:

function AllowOutbound
{
  param( [string]$name, [string]$path, [string]$protocol, [string]$port)
  Write-Output "[+]: '$name' ($path) -> ${protocol}:$port"
  New-NetFirewallRule -DisplayName $name -Description $path -Program $path -Direction Outbound -Group 'USER' -Protocol $protocol -RemotePort $port
}


Подписаться
Уведомление о
guest
0 Комментарий
Inline Feedbacks
View all comments