Задать вопрос
@NewDevLab

Как сделать выполнение не в виде строки, а в виде блока?

Сейчас всё работает так:
Функции

function Test-IsAdmin() {
	return ( [Security.Principal.WindowsPrincipal] ([Security.Principal.WindowsIdentity]::GetCurrent())
		).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
Set-Alias IsAdmin Test-IsAdmin

function Invoke-CommandExt() {
	param (
		[Alias("Command")] [parameter(Mandatory=$true, ValueFromPipeline = $true)] [ValidateNotNullOrEmpty()]
			[string[]] $cmd,
		[Alias("Wait")] [parameter(Mandatory=$false)]
			[bool] $isWait = $true,
		[Alias("VerbRunAs")] [parameter(Mandatory=$false)]
			[bool] $isVerbRunAs = $false,
		[Alias("Pause")] [parameter(Mandatory=$false)]
			[bool] $isPause = $false,
		[Alias("Echo")] [parameter(Mandatory=$false)]
			[bool] $isEcho = $false
	)
	BEGIN {
		[System.Collections.ArrayList] $listCmds = new-object System.Collections.ArrayList
	}
	PROCESS {
		[void] $listCmds.AddRange($cmd)
	}
	END {

		[string] $cmds = [string]::Join([Environment]::NewLine, $listCmds.ToArray())
		# Эхо команды на экран
		if ($isEcho) {
			Write-Host "*** Echo Start ***"
			Write-Host $cmds.ToString() -ForegroundColor Gray
			Write-Host "*** Echo End ***"
		}
		#Write-Host "Wait = $isWait, VerbRunAs = $isVerbRunAs, IsAdmin = $(Test-IsAdmin)"	

		# Расширяем команду до ожидания нажатия после выполнения
		[string] $cmdExt = if ($isPause) {
				#$cmd = "& {$Command; pause}"
				#While ([Console]::ReadKey(`$true).Key -notin @([ConsoleKey]::Enter, [ConsoleKey]::Escape)) {};
				"& {$cmds
					Write-Host `"Нажмите [AnyKey] для продолжения…`" -ForegroundColor Gray; [Console]::ReadKey(`$true);}"
				#Write-Host $cmdExt -ForegroundColor Gray
			} else {
				"& {$cmds}"
			}
		[string] $cmdExtWithoutPause = "& {$cmds}"

		# Выполняем команду
		if ($isWait) {
			# Ждём завершения выполнения команды
			if ($isVerbRunAs) {
				# Проверка необходимости повышения привилегий
				if (IsAdmin) {
					Invoke-Expression $cmdExtWithoutPause # не учитываем $isPause
				} else {
					$bytes = [System.Text.Encoding]::Unicode.GetBytes($cmdExt)
					[array] $argumentList = @("-NoProfile", "-ExecutionPolicy Bypass", "-encodedCommand", [Convert]::ToBase64String($bytes))
					Start-Process -FilePath "PowerShell" -argumentlist $argumentList -Wait -Verb runAs
				}
			} else {
				Invoke-Expression $cmdExtWithoutPause # не учитываем $isPause
			}
		} else {
			# Не ждём завершения выполнения команды, всегда новая консоль
			$bytes = [System.Text.Encoding]::Unicode.GetBytes($cmdExt)
			[array] $argumentList = @("-NoProfile", "-ExecutionPolicy Bypass", "-encodedCommand", [Convert]::ToBase64String($bytes))
			if ($isVerbRunAs) {
				Start-Process -FilePath "PowerShell" -argumentlist $argumentList -Verb runAs
			} else {
				Start-Process -FilePath "PowerShell" -argumentlist $argumentList
			}
		}

	}
}



и вызывается так:
".`"$(Join-Path $PathToBinFolderTap "tapinstall.exe")`" install '$(Join-Path $PathToBinFolderTap "OemVista.inf")' tap0901" |
		<#Shell.Invoke.#>Invoke-CommandExt -Wait $true -VerbRunAs $true -Pause $true -Echo $false

хотелось бы избавиться от лишних кавычек/экранов при вызове и писать не строку а код.
  • Вопрос задан
  • 116 просмотров
Подписаться 2 Простой 2 комментария
Пригласить эксперта
Ответы на вопрос 1
@MaxKozlov Куратор тега PowerShell
Ну, никто ведь не мешает вызывать скриптблоки и конструировать их именно как скриптблоки
$myscriptblock = { mysupercommand $args }
& $myscriptblock $myparams

можно даже параметры передавать
$scriptblock = { param($fg,$bg, $text) Write-Host -Foreground $fg -Background $bg $text }
& $scriptblock yellow blue text

Причём при их конструировании даже с using морочиться не надо
PS> $text = 'first'
PS> $sb = { "my Text - $text" }
PS> & $sb
my Text - first
PS> $text = 'second'
PS> &$sb
my Text - second


при большом желании сделать мультитул можно нагромоздить нечто такое
function Invoke-MyTool {
param(
[ValidateSet('ping','write')]
[parameter()]
[string]$cmd,
 [parameter(mandatory=$false,  position=1, ValueFromRemainingArguments=$true)]$args
)
)
$config = @{
ping = { ping },
'write' = { param($text, $fg, $bg)  write-host $text -fore $fg -back $bg }
}
& $config[$cmd] $args
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы