在PS 5.0中,我可以像这样在一行中分割和修剪字符串
$string = 'One, Two, Three'
$array = ($string.Split(',')).Trim()
Run Code Online (Sandbox Code Playgroud)
但这在PS 2.0中失败了。我当然可以做一个foreach以调整每个项目,或更换', '与','做分开过,但我不知道是否有一个更优雅的方式,在PowerShell中的所有版本的作品?失败的话,替换似乎是用单个代码库解决所有版本的最佳方法。
我注意到但从未见过任何解释的是这个奇怪的小“事实”。我可以从 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 类最佳实践,但在使用一个简单的类来处理气球提示时遇到了一些困惑。
Add-Type -assemblyName:System.Drawing
Add-Type -assemblyName:System.Windows.Forms
class PxMessage {
static [PxMessage] $instance
static $balloon
static $defaultIcon
static [PxMessage] GetInstance($processIcon) {
if ([PxMessage]::instance -eq $null) {
[PxMessage]::instance = [PxMessage]::new()
#[PxMessage]::balloon = [Windows.Forms.NotifyIcon]::new()
[PxMessage]::balloon = New-Object Windows.Forms.NotifyIcon
[PxMessage]::defaultIcon = $processIcon
}
return [PxMessage]::instance
}
[Void] SendMessage ([String]$title, [String]$message, [String]$messageIcon) {
[PxMessage]::balloon.icon = [PxMessage]::defaultIcon
[PxMessage]::balloon.balloonTipTitle = $title
[PxMessage]::balloon.balloonTipText = $message
[PxMessage]::balloon.balloonTipIcon = $messageIcon
[PxMessage]::balloon.visible = $true
[PxMessage]::balloon.ShowBalloonTip(0)
[PxMessage]::balloon.Dispose
}
}
$processIcon = [System.Drawing.Icon]::ExtractAssociatedIcon($(Get-Process -id:$PID | Select-Object -expandProperty:path))
$message = [PxMessage]::GetInstance($processIcon)
$message.SendMessage('Title', "$(Get-Date)", …Run Code Online (Sandbox Code Playgroud) 我的理解是(数学上)0是Int.但是
if (0 -as [int]){"Int"}else{"Not"}
Run Code Online (Sandbox Code Playgroud)
回归Not,至少对我来说是PS 2.0.
这是v2中的错误,还是我误解了事情?我已经通过测试解决了这个问题-as [int] -and -ne 0,但这是相当愚蠢的感觉,所以我希望我在这里遗漏了一些东西并且有一个更好的答案.
仅供参考,我专门处理需要添加初始索引的种子计算机名称或需要增加索引的最后一个计算机名称.种子看起来像Lab 1-,初始索引可以是0或者可以是1,具体取决于具体情况.我只是在测试最后一个角色[int],知道 - 不会是一个int.但是当第一台计算机是实验室1-00因为初始索引为0时,我也得不到[int]而且事情变得很难看,下一台计算机是Lab 1-0000.再一次,额外的条件是有效的,只是想知道我是否误解了我的期望0是一个[int].
是否有单一的保证方法来测试当前用户是否具有管理员权限?我试过这个
$isAdmin = (new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole("Administrators")
Run Code Online (Sandbox Code Playgroud)
只要 Windows 最初是用英文安装的,它就可以工作。如果 Windows 以西班牙语安装,您必须测试 Administra d ors。还有一些其他语言的工作方式类似。我的第一个想法是测试所有可能的拼写,但如果有一些简单、优雅和万无一失的东西,那将是我的首选。
我已经成功地使用[environment]::getfolderpath("ProgramFiles"),以获得路径程序文件,但现在我有必要还可以访问程序数据,它看起来从这个枚举像ProgramData不可用此方法。是真的,还是我在这里想念东西?
我想在验证该参数之前测试是否提供了特定的命名参数,以便我可以为缺失和无效条件提供有意义的错误代码。我现在有这个
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set colArgs = WScript.Arguments.Named
If colArgs.Item("Script") Then
If not objFSO.FileExists(colArgs.Item("Script")) Then
intReturn = 1805
End If
Else
intReturn = 1639
End If
If Not intReturn Then
msgBox colArgs.Item("Script"), 0, "Script"
Else
msgBox intReturn, 0, "Error"
End If
Run Code Online (Sandbox Code Playgroud)
我的期望是,如果我根本不提供名为 Script 的参数,我会得到值为 1639 的 Error msgBox 。相反,我得到了很好的 msgBox,脚本为空白。我也试过
If Not colArgs.Item("Script") = "" Then
Run Code Online (Sandbox Code Playgroud)
编辑:根据@Tomalak,我现在有了这个
Option Explicit
Dim objShell, objFSO, colArgs, intReturn
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set colArgs = …Run Code Online (Sandbox Code Playgroud) 我在排序的哈希表中看到一些看似非常奇怪的行为,然后尝试查看结果。我构建了哈希表,然后我需要根据值对该表进行排序,我看到了两个奇怪的地方。
这在课堂外工作正常
$hash = [hashtable]::New()
$type = 'conformset'
$hash.Add($type, 1)
$type = 'applyset'
$hash.Add($type , 1)
$type = 'conformset'
$hash.$type ++
$hash.$type ++
$hash
Write-Host
$hash = $hash.GetEnumerator() | Sort-Object -property:Value
$hash
Run Code Online (Sandbox Code Playgroud)
我看到散列的内容两次,未排序然后排序。然而,当使用一个类时它什么也不做。
class Test {
# Constructor (abstract class)
Test () {
$hash = [hashtable]::New()
$type = 'conformset'
$hash.Add($type, 1)
$type = 'applyset'
$hash.Add($type , 1)
$type = 'conformset'
$hash.$type ++
$hash.$type ++
$hash
Write-Host
$hash = $hash.GetEnumerator() | Sort-Object -property:Value
$hash
}
}
[Test]::New()
Run Code Online (Sandbox Code Playgroud)
这只是将 Test 回显到控制台,与哈希表无关。我的假设是,它与管道如何中断有关,老实说,考虑到管道错误的常见污染程度,这是转移到类的一个很好的理由。因此,转向基于循环的方法,这无法显示类中的第二个已排序、已排序的哈希表。
$hash …Run Code Online (Sandbox Code Playgroud) 我可以Generic.List用我的类的实例填充 a ,每个实例在 ID 属性中都有一个唯一的值,就像这样。
$packages = [System.Collections.Generic.List[object]]::New()
class Package {
# Properties
[String]$ID
# Constructor
Package ([String]$id) {
$this.ID = $id
}
}
foreach ($i in 65..90) {
$packages.Add([Package]::New("$([char]$i)"))
}
Run Code Online (Sandbox Code Playgroud)
现在我想获取特定项目的索引,沿着$packages.IndexOf('C'). 但是在 C# 中这样做似乎需要使用 lambda,而 PowerShell 似乎不支持。我宁愿不必初始化我自己的索引变量并遍历列表中的所有项目,检查它们的 ID 并在此过程中增加索引。但是,也许这就是仅使用带有本机 PS cmdlet 的 PowerShell 和仅使用 C# 之间的灰色区域,您在这两种极端情况下都错过了糖,而必须自己制作?
我在Uninstalls注册表项中有一个程序,奇怪的日期/时间.报告的值为"1533407816",但实际日期很可能是"20180804",这是当天安装的所有其他Autodesk产品的报告.我正在使用[datetime]::ParseExact($program.GetValue('InstallDate'),'yyyyMMdd',$null)将这些日期转换为正确的DateTime,但不确定我需要什么机制来进行奇怪的日期.或者,如果它甚至是有意义的数据.
我需要实现一个查找表方案。我COULD利用哈希表做。所以
$fruit = @{
0 = 'Apple'
1 = 'Pear'
2 = 'Kiwi'
}
$fruit[1]
Run Code Online (Sandbox Code Playgroud)
但是在我看来,ENUM是正确的本机数据类型。但是,虽然我可以获取特定枚举名称的索引,但似乎无法通过引用值/索引来获取名称。这不起作用。
Enum Fruit {
Apple
Pear
Kiwi
}
[fruit]::1
Run Code Online (Sandbox Code Playgroud)
我只是完全不了解ENUM吗?因为在我看来,使用查找索引与[fruit]::'Pear'.value__我想做的相反。
对于上下文,我想有一个ENUM,它为从中获取的整数提供相应的字符串
(Get-WmiObject -class:Win32_ComputerSystem -computerName:. -nameSpace:'root\CIMV2').PCSystemType
Run Code Online (Sandbox Code Playgroud)
最后,我想将这些ENUM本地化为PSD1文件,因此当PCSystemType为2时,我的法语用户将获得“ Portable”,而英语用户则将获得“ Mobile”。注意,我实际上不确定“ Portable”是否正确,我需要找一个朋友来进行本地化,但是您明白了。
无论如何,在给定索引的情况下,是否有直接到达名称的路径?还是将枚举强制为数组或哈希表的唯一选择,此时没有理由使用枚举?
编辑:@ andy-arismendi在这里回答了:: ::问题。它正在调用[fruit]类型的静态方法,这不是我们想要的。而且,由于它是.NET类型,我想也需要.NET方式来引用索引,而该索引不需要像PowerShell一样使用[#]?更多学习!;)
我需要/想要[System.Collections.Generic.List[string]]从函数返回 a ,但它被包含在一个System.Object[]
我有这个
function TestReturn {
$returnList = New-Object System.Collections.Generic.List[string]
$returnList.Add('Testing, one, two')
return ,@($returnList)
}
$testList = TestReturn
$testList.GetType().FullName
Run Code Online (Sandbox Code Playgroud)
它将它作为 a 返回System.Object[],如果我将返回行更改为
return [System.Collections.Generic.List[string]]$returnList
Run Code Online (Sandbox Code Playgroud)
或者
return [System.Collections.Generic.List[string]]@($returnList)
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,当[System.String]列表中有一项时,它返回 a ,System.Object[]如果有多个项,则返回 a 。列表有什么奇怪的地方不能用作返回值吗?
现在,奇怪的是(我认为)如果我像这样键入接收值的变量,它确实有效。
[System.Collections.Generic.List[string]]$testList = TestReturn
Run Code Online (Sandbox Code Playgroud)
但这似乎是某种奇怪的强制转换,其他数据类型不会发生这种情况。
例如,我一直[Linq.Enumerable]::SequenceEqual()用来比较两个数组中项目的顺序
$validOrder = @('one', 'two', 'three')
$provided = @('one', 'two', 'three')
[Linq.Enumerable]::SequenceEqual($validOrder, $provided)
Run Code Online (Sandbox Code Playgroud)
这有效,但现在我意识到我想独立解决大写错误,所以我想以不区分大小写的方式测试订单。我发现这记录了一个不同的方法签名,IEqualityComparer<T>作为第三个值。这确实看起来是正确的方向,但我还没有找到任何可以帮助我在 powershell 中实现它的东西。我尝试只使用 'OrdinalIgnoreCase' 作为最后一个参数,[String].FindIndex()正如另一个线程中指出的那样。但可惜不是这里。我还发现这实际上为不同的对象类型制作了一个自定义比较器,但似乎我刚刚手动实现了我真正想要的东西,我不确定使用的价值是什么[Linq.Enumerable]::SequenceEqual(),我可以将我的数组传递给我的类方法并直接在那里完成工作。
如果 (-not (Compare-Object -SyncWindow 0 $validOrder $provided)) { $result = 'ordered' } else { $result = 'disordered' } 并且它已经不区分大小写,我也使这种方法有效。但它也更慢,我可能有很多这样的测试要做,所以速度会有好处。
最后,我看到这似乎有效,并且非常简单,不区分大小写(如果我愿意)并且看起来很快。数组中的项目总数总是很小,不同数组的重复次数是性能问题。
$result = ($provided -join ' ') -eq ($validOrder -join ' ')
Run Code Online (Sandbox Code Playgroud)
那么,最后一个选项是否可行,或者我是否遗漏了一些明显反对它的内容?
另外,我觉得我还会IEqualityComparer<T>遇到其他有用的论点,因此知道如何去做会很有用。假设我读对了,并IEqualityComparer<T>提供了一种不同形式的比较机制,而不仅仅是滚动我自己的比较。
powershell ×12
class ×2
generic-list ×2
.net ×1
datetime ×1
enums ×1
hashtable ×1
indexof ×1
integer ×1
linq ×1
properties ×1
registry ×1
return-type ×1
sorting ×1
text-parsing ×1
vbscript ×1
zero ×1