小编Gor*_*don的帖子

扩展存档奇怪错误

我正在尝试获取 Autodesk Revit 文件中的一些数据,该文件只是皮肤下的 ZIP。我可以使用 7zip 进行解压,但我希望能够使用所有本机 PS 或 Windows 实现自动化操作。在将 RVT 文件重命名为 ZIP 后,我尝试了 Expand-Archive,但 Expand-Archive 有一个奇怪的错误。代码是

Expand-Archive -path:'C:\RevitVersionTest\22-PLUMB-CLR-RECTANGULAR.zip' -destinationPath:'C:\Revit Fam'
Run Code Online (Sandbox Code Playgroud)

错误是

新对象:使用“3”个参数调用“.ctor”时出现异常:“无法找到中央目录记录末尾。”

powershell unzip

8
推荐指数
1
解决办法
1万
查看次数

Powershell对象:引用Self

我可以用这样的四个属性创建一个对象

$pocketKnife = New-Object PSObject -property @{
    Color = 'Black'
    Weight = '55'
    Manufacturer = 'Buck'
    Blades = '1'
}
Run Code Online (Sandbox Code Playgroud)

并且基本上按预期工作.但是,我似乎无法理解如何添加引用对象自己的属性的方法.我可以加上这个

$pocketKnife | Add-Member ScriptMethod GetColor {
    Write-Host "Color = $($pocketKnife.Color)" 
}
Run Code Online (Sandbox Code Playgroud)

然后我可以调用$ pocketKnife.GetColor()并按预期工作.但是我必须将对象引用硬连接到方法中,并且实际上我引用了在对象本身之外定义的对象变量.我想做的是

$pocketKnife | Add-Member ScriptMethod GetColor {
    Write-Host "Color = $($Self.Color)" 
}
Run Code Online (Sandbox Code Playgroud)

最后,我想创建一个Logger对象,它将初始化自身并在属性中建立适当的日志文件名,并且具有一个采用字符串参数的Log方法,并且在调用时它会记录到属性中的日志文件.我觉得这可能不仅仅是PowerShell真正打算面向对象.就像我应该将我的(自定义)对象的概念限制为结构的数据,而不是类和实例?FWIW,我对OOP足够新,我不知道我不知道什么.我所知道的是,现在我正在使用全局变量作为日志文件路径,以及引用它的init和log函数,我正在寻找消除全局变量的最佳方法,并且还使用PS来实现它的潜力,并在我学习时学习一些编程概念.而且我的所有Google Fu最终都会获得有关对象属性的更多信息,而不仅仅是简单示例之外的方法,它们会回显一些文本以证明您在方法中.因此,任何建议都非常感谢,即使它只是"不是那个树"

谢谢!

powershell object self

5
推荐指数
1
解决办法
3419
查看次数

全局变量用例

我有一些脚本和模块,它们使用全局变量来处理许多事情.我的日志记录可以采用三种形式之一; Terse,Verbose和Validation(详细记录没有实际操作,只是验证提供的数据).我还有许多函数,这些函数根据它们运行的​​上下文(用户或机器)做出不同的响应,并且正在执行的Action(Rollout,Remove,Conform,Relocate)也会影响事物.所以,到目前为止,我已经使用了三个全局变量并且它已经有效,但我知道最佳实践是避免全局变量.也就是说,解决它的唯一方法似乎是在一个模块中使用一些Get和Set函数,以及Script级别变量.这似乎增加了复杂性而没有真正解决太多,因为我仍然有比使用它们的函数更高的变量.或者,我可以将这三个值传递给需要它们的每个函数,但也有很多参数几乎没有增加价值.所以我开始想知道,这是一个全局变量确实是正确答案的地方吗?它们的存在表明必须存在一些应该使用它们的情况,并且这种情况开始变得恰到好处.

powershell global-variables

5
推荐指数
2
解决办法
931
查看次数

PS1文件的正确编码是什么

我正在对一系列PS1和PSM1文件进行一些文本流处理,我遇到了一些智能引号和em-dashes的问题(永远不会,从MS Scripting Guy博客剪切和粘贴代码).我认为问题是编码所以我看了,我有ASCII和UTF8的文件,但当然两个都有我的时髦文本的问题.所以我做了一些替换,我有这个工作,但我想知道我是否也不应该对一种编码进行标准化,如果是,那么哪一种?

powershell character-encoding

5
推荐指数
2
解决办法
1636
查看次数

通过带有返回码的 VBS 隐藏 PS 窗口

我正在尝试使用 VBScript 帮助程序脚本在隐藏窗口中启动 PowerShell 脚本。我已经成功地这样做了一段时间,但现在我想添加获取返回码,这使事情变得更加复杂。获取返回码的常用方法是使用 .Exec 而不是 .Run,​​但是这样您就失去了隐藏命令窗口的能力。我找到了这个线程,并基于它和一个已知的工作strCMD,我尝试了

strCMD = strCMD & " > c:\out.txt"
objShell.Run strCMD, 0, True
Run Code Online (Sandbox Code Playgroud)

但这不起作用。我哪里出错了有什么建议吗?或者有关获取带有返回码的隐藏 Powershell 脚本的更好方法的建议?FWIW,我必须针对 PS 2.0。:(

为了完整起见,strCMD 的值是

powershell -noLogo -noProfile -file "C:\Program Files\PragmaticPraxis\Resources\TestMessage.ps1" -message:"I'M ALIVE!!!" -message2:"Me too!"
Run Code Online (Sandbox Code Playgroud)

而 TestMessage.ps1 只是

[CmdletBinding()]
param (
    [string]$message,
    [string]$message2
)

[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > $null
[System.Windows.Forms.MessageBox]::Show($message)
[System.Windows.Forms.MessageBox]::Show($message2)
Run Code Online (Sandbox Code Playgroud)

编辑:多亏了 omegastripes 的链接,我正在尝试实现此实现的更通用和 PowerShell 重点版本,并通过一些代码重构来消除对函数的一次性调用和尴尬的强制退出。我有的是这个:

Option Explicit
Dim strCmd, strRes, objWnd, objParent, strSignature

If WScript.Arguments.Named.Exists("signature") Then 
    For Each objWnd In CreateObject("Shell.Application").Windows
        If IsObject(objWnd.getProperty(WScript.Arguments.Named("signature"))) Then Exit For …
Run Code Online (Sandbox Code Playgroud)

vbscript powershell

5
推荐指数
1
解决办法
875
查看次数

抑制数组列表添加方法管道输出

我正在使用数组列表来构建日志项序列以供稍后记录。工作起来很不错,但是 Add 方法将当前索引发送到管道。我可以通过将其发送到 $null 来解决这个问题,如下所示

$strings.Add('junk') > $null
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有某种机制可以全局更改 Add 方法的行为。现在我确实有数百次> $null重复,这真是丑陋。尤其是当我忘记一个的时候。

我真的很想看到某种全局变量来抑制所有自动流水线。在编写大型脚本时,我想有意发送到管道,因为意外的自动发送到管道是我的总错误的很大一部分,也是最难发现的。

powershell pipeline

5
推荐指数
1
解决办法
1811
查看次数

Powershell防弹异常处理

我正在将一个非常大的基于函数的脚本迁移到类,并同时尝试启动我的错误捕获游戏。代码要么通过作业在远程机器上运行,要么在用户登录时自动且透明地运行,日志文件是传达问题的唯一方式。当前(基于函数的)版本有一些错误会导致未处理的异常,这意味着这些问题永远不会记录在日志中。代码读取用户提供的 XML 文件以进行数据处理,我需要提供有意义的反馈,以便可以处理数据或数据结构。我的总体目标是... 1:捕获所有异常。2:在视觉上区分“预期”异常;我在日志中提供了一些有用的信息以允许用户进行故障排除和“意外”异常;我提供脚本名称和行号来帮助我追踪错误。3:随着时间的推移,将尽可能多的项目从“意外”移动到“预期”。

考虑到这些目标,我正在考虑几件事,但我觉得我知道的还不够多,无法确保我的决策是正确的。1:$ErrorActionPreference=Stop历史上的建议是不要设置全局错误操作,而是根据具体情况进行操作。但是考虑到我可以将它设置为停止的每一种情况,我都会,似乎这个建议实际上更多是关于快速“脚本”,而我基本上是使用 PS 来编写“程序”,而全局停止是更好的答案?

2:鉴于这样的场景,我在一个实用程序方法中有一个异常(不,我没有在这里实现一个类,我试图让示例保持简单,但希望这个概念仍然清晰)...

$path = '\\Server\InvalidFolder|'
try {
    Test-Path $path -errorAction:stop
} catch [System.ArgumentException] {
    throw [Custom.ExpectedException] "Error: Invalid characters in path - $invalidCharacters"
} catch {
    # Generic error trap
    throw [Custom.UnexpectedException] "Unexpected Error: $($_.ScriptStackTrace) $($_.Exception.Message)"
}
Run Code Online (Sandbox Code Playgroud)

我觉得我想要/需要做的是创建一些自定义错误类型,这样我就可以捕获不同的 Powershell 错误并将它们转换为我的类型,然后我抛出,并且调用代码有自己的 try/catch 然后格式化并推送到日志。这是正确的方法,还是我错过了一些更好的选择?3:假设这甚至是可能/可取的,如何创建自定义异常类型?我的 Google-Fu 失败了,这让我想知道我是否找不到任何东西,因为它不能/不应该完成。

编辑:就自定义异常类型而言,这看起来工作正常。

class PxException : Exception {
    PxException() {
    }

    PxException([string] $message): base($message) {
    }

    PxException([string] $message, [Exception] $inner) : base($message, $inner) {
    }
}


$path = '\\Server\InvalidFolder|'
try …
Run Code Online (Sandbox Code Playgroud)

oop powershell exception

5
推荐指数
0
解决办法
99
查看次数

ArrayList .Add 与 .AddRange 相对于管道

给定一个正确定义的变量

$test = New-Object System.Collections.ArrayList
Run Code Online (Sandbox Code Playgroud)

.Add用数组中的项目数污染管道,而.AddRange不会。 $test.Add('Single')将把计数转储到控制台。$test.AddRange(@('Single2'))无需额外努力即可干净。为什么会有不同的行为?这只是一个疏忽,还是有一些我不理解的故意行为?

鉴于.AddRange在不使用变量(已经是一个数组)时需要强制到数组,[void]$variable.Add('String')当我知道我只需要添加一项时,以及[void]$test.AddRange($variable)当我向数组添加一个数组时,即使$variable只包含一个项目,我倾向于使用,或只能包含单个项目。这里[void]不是必需的,但我想知道拥有它是否是最佳实践,当然取决于上面的答案。或者我也错过了一些东西吗?

powershell pipeline arraylist

5
推荐指数
1
解决办法
6075
查看次数

为什么 PowerShell [TYPE]::new() 是小写

我注意到但从未见过任何解释的是这个奇怪的小“事实”。我可以从 Powershell 调用的大多数(全部?)类方法都使用 Pascal Case。例如

[System.IO.FileInfo].FullName
$xmlWriter.WriteStartDocument()
[System.GC]::Collect()
Run Code Online (Sandbox Code Playgroud)

还有很多。但我一直看到的一个例外是新的。New(几乎?)总是小写。键入[xml.xmlReaderSettings]::和提供的有用下拉列表是Equals, new& ReferenceEquals。这一直发生,我怀疑这不是巧合,所以我希望有人能解释为什么。我的想法是,由于命名约定是公共方法和参数使用 Pascal Case(而私有方法和参数使用 Camel Case)并且 []::new 既不是属性也不是参数,它间接调用了构造函数,它得到了Camel Case?或者甚至不是 Camel Case,只是小写,在这种情况下看起来是一样的。

我知道在 PowerShell 中这无关紧要,只是好奇底层逻辑是什么。

powershell class naming-conventions

4
推荐指数
1
解决办法
113
查看次数

基于另一个数组对一个数组进行度假村

我希望基于另一个数组来使用一个数组。在之前的项目中,我只需要获取无序项目的列表,然后将该代码应用到我当前的场景中,我得到了这个

$definedSet = @('C', 'B', 'D', 'A')
$history = @('A', 'B', 'C', 'D')

$disordered = $history.Where({-not [Linq.Enumerable]::SequenceEqual([string[]]$history, [string[]]$definedSet)})
$disordered
Run Code Online (Sandbox Code Playgroud)

这确实给了我所有四个项目的列表,因为它们都是乱序的。然而,在这个新场景中我需要诉诸$history基于$definedSet. 关键是其中一个中可能存在另一个中没有的项目。但我从一个更简单的问题开始,这让我很困惑。显然,我觉得确定[Linq.Enumerable]是关键,但我的 Google-Fu 并没有为我指明解决方案。我已经尝试过有关 Enumerable 类的 Microsoft Docs 文章,我的大脑...融化了。

sorting powershell enumerable

4
推荐指数
1
解决办法
188
查看次数