Out-File 似乎在使用UTF-8时强制BOM:
$MyFile = Get-Content $MyPath
$MyFile | Out-File -Encoding "UTF8" $MyPath
Run Code Online (Sandbox Code Playgroud)
如何使用PowerShell以UTF-8编写没有BOM的文件?
我编写了函数'A',它将调用许多其他函数之一.为了保存重写函数'A',我想传递函数作为函数'A'的参数调用.例如:
function A{
Param($functionToCall)
Write-Host "I'm calling : $functionToCall"
}
function B{
Write-Host "Function B"
}
Function C{
write-host "Function C"
}
A -functionToCall C
Run Code Online (Sandbox Code Playgroud)
返回:我正在打电话:C
我期待它回归:我在呼唤:功能C.
我尝试了各种各样的东西,比如:
Param([scriptblock]$functionToCall)
Run Code Online (Sandbox Code Playgroud)
无法将System.String转换为ScriptBlock
A -functionToCall $function:C
Run Code Online (Sandbox Code Playgroud)
返回"写主机"功能C"
A - functionToCall (&C)
Run Code Online (Sandbox Code Playgroud)
这在其余部分之前进行评估:
Function C
I'm Calling :
Run Code Online (Sandbox Code Playgroud)
我确定这是编程101,但我无法弄清楚正确的语法或它是什么我做错了.我们将非常感激地提供任何帮助.非常感谢.
我不经常使用 Powershell 或 Linux,所以我不确定: ls -al 在 Powershell“术语”中是什么。我试图找到一些东西,但它说 Powershell 中没有等效的命令。看起来很奇怪,所以我想我应该尽快问一下。
以字符串而不是对象形式输出结果的命令:
ls | Out-String -Stream
Run Code Online (Sandbox Code Playgroud)
输出:
Directory: C:\MyPath\dir1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2022-01-22 5:34 PM 0 1.txt
-a--- 2022-01-22 5:34 PM 0 2.txt
-a--- 2022-01-22 5:34 PM 0 3.txt
Run Code Online (Sandbox Code Playgroud)
我尝试使用函数获得相同的结果:
function f {
[CmdletBinding()]
param (
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
$Content
)
process {
$Content | Out-String -Stream
}
}
ls | f
Run Code Online (Sandbox Code Playgroud)
但是,每个项目的输出都是分开的:
Directory: C:\MyPath\dir1
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2022-01-22 5:34 PM 0 1.txt
Directory: C:\MyPath\dir1
Mode LastWriteTime Length Name
---- …Run Code Online (Sandbox Code Playgroud) 我设置了我的 powershell 配置文件来创建常用命令的别名。在 Microsoft 的文档中,它说,如果我想为带有参数的命令创建别名,我应该将别名的值设为执行此操作的函数。
. 但是,当我在命令行中键入函数的名称时,它与别名一样有效。
换句话说,在上图中,如果我输入,CD32它的行为与我Go在命令行中输入的行为相同
所以我的问题是:当我可以拥有一个函数时,为什么要使用指向函数的别名?两者之间有功能差异吗?
考虑以下简单函数:
function Write-HostIfNotVerbose()
{
if ($VerbosePreference -eq 'SilentlyContinue')
{
Write-Host @args
}
}
Run Code Online (Sandbox Code Playgroud)
而且效果很好:
现在我想让它成为一个高级函数,因为我希望它继承详细程度首选项:
function Write-HostIfNotVerbose([Parameter(ValueFromRemainingArguments)]$MyArgs)
{
if ($VerbosePreference -eq 'SilentlyContinue')
{
Write-Host @MyArgs
}
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用:
让我抓狂的是,我无法确定第一个示例与第二$args个示例有何不同。$args
我知道@args默认情况下本机泼溅不适用于高级功能 - https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_splatting?view=powershell-7.2#notes
但我希望可以模拟,但也行不通。我的问题是 - 我尝试模拟它的方式有什么问题,以及是否可以在不显示所有参数的Write-Host情况下修复我的代码Write-HostIfNotVerbose
powershell arguments function function-call parameter-splatting
我正在尝试为 Pester 的 cmdlet 创建一个包装器(代理)Should。可能的用例包括即使在成功的情况下也可以透明地记录测试输入,并改进 Pester 记录某些类型对象的方式,例如hashtable.
作为Should一个高级函数,通过$argssplatting 转发参数不起作用。
所以我尝试使用生成一个包装器,如这个答案System.Management.Automation.ProxyCommand::Create()所述:
$cmd = Get-Command Should
$wrapperSource = [System.Management.Automation.ProxyCommand]::Create( $cmd )
$wrapperSource >should_wrapper.ps1
Run Code Online (Sandbox Code Playgroud)
调用包装器时,Powershell 输出以下错误消息:
应该:无法使用指定的命名参数解析参数集。发出的一个或多个参数不能一起使用或提供的参数数量不足。
看起来包装器生成器不理解 的动态参数声明Should。
如何在Should不重复 Pester 代码的情况下为 Pester 编写通用包装器?
我正在编写一个脚本,我想传递这些值,但也想看到它们显示
Get-Content data.txt | Tee-Object | data_processor.exe
Run Code Online (Sandbox Code Playgroud)
但Tee-Object总是请求一个文件,我只想在屏幕上看到它。
我是 PowerShell 的新手。在 Msys2(或 Lnux)中,我定义了一个函数npp
npp ()
{
${NPP_PATH} "$@"
}
Run Code Online (Sandbox Code Playgroud)
这样,如果我从命令提示符调用,npp它会启动 Notepad++(如 中所定义${NPP_PATH})。如果我调用npp "mydir/stage 1/a.txt"它会打开该文件进行编辑。一般来说,它允许:
PowerShell 中的等价物是什么?
我想在 PS 我也应该去寻找一个函数来获得类似的行为。到目前为止,我可以接收未定义数量的参数,并在foreach循环中使用它们,请参阅下面的代码。但是我找不到简单的等价物"$@"来传递接收到的所有参数。此外,如果我在其中一个参数中使用引号,它们将被删除,因此文件路径可能会出现问题,包括空格。
function multi_params {
param(
[Parameter(
ValueFromRemainingArguments=$true
)][string[]]
$listArgs
)
$count = 0
foreach($listArg in $listArgs) {
'$listArgs[{0}]: {1}' -f $count, $listArg
$count++
}
}
Run Code Online (Sandbox Code Playgroud) 我使用下面的代码来显示 PowerShell 作业的结果,超时时间为 120 秒。我想通过合并Write-Progress(基于完成的作业数量)来增强此代码。我尝试使用此示例作为参考,但是,当我尝试合并该代码时,进度条会在所有作业全部完成后短暂显示。
$Jobs = @()
$ForceStoppedIds = @{}
$Jobs += Get-Job
$Jobs | Wait-Job -Timeout 120 | Out-Null
$Jobs | ?{$_.State -eq 'Running'} | Stop-Job -PassThru | %{$ForceStoppedIds[$_.Id] = $true}
foreach ($Job in $Jobs) {
$Name = $Job.Name
$Output = (Get-Job -Name $Name | Receive-Job)
if ($ForceStoppedIds.Contains($Job.Id)) {
Write-Output "$($Name) - Device unable to process request within 2 minutes"
} else {
Write-Output $Output
}
}
Run Code Online (Sandbox Code Playgroud) 我正在编写一个使用 ValueFromRemainingArguments 包装 cmdlet 的函数(如此处所述)。
下面的简单代码演示了这个问题:
function Test-WrapperArgs {
Set-Location @args
}
Run Code Online (Sandbox Code Playgroud)
Test-WrapperArgs -Path C:\
Run Code Online (Sandbox Code Playgroud)
Test-WrapperArgs -Path C:\
Run Code Online (Sandbox Code Playgroud)
Test-WrapperUnbound -Path C:\
Set-Location: F:\cygwin\home\thorsten\.config\powershell\test.ps1:69
Line |
69 | Set-Location @UnboundArgs
| ~~~~~~~~~~~~~~~~~~~~~~~~~
| A positional parameter cannot be found that accepts argument 'C:\'.
Run Code Online (Sandbox Code Playgroud)
我尝试通过 PowerShell 社区扩展来解决该问题,GetType但EchoArgs没有成功。目前我几乎正在考虑一个错误(可能与这张票有关??)。