我想回来谈谈 Hashtables.。我现在一直在使用这些时间。在昨晚我们的用户团体会议之后,我教导了某人,我意识到我起初对他们同样混淆了他。 Hashtables在PowerShell中非常重要,因此对他们有牢固的理解是件好事。

指数

哈希可作为一系列的集合

我希望您首先在传统的哈希特定义中看到哈希表作为集合。这为您提供了对他们在以后更高级的更高级的方式工作的基本理解。跳过这种理解通常是混乱的源泉。

什么是数组?

在我跳入哈希特的东西之前,我需要提及 阵列 第一的。出于本讨论的目的,数组是值或对象的列表或集合。

$array = @(1,2,3,5,7,11)

Once you have your items into an array, you can either use foreach to iterate over the list or use an index to access individual elements in the array.

foreach($item in $array)
{
    Write-Output $item
}

Write-Output $array[3]

您还可以以相同的方式使用索引更新值。

$array[2] = 13

我刚刚在阵列上划伤了表面,但应该将它们放入正确的上下文,因为我移动到Hashtables。

什么是哈希特?

我将首先,通过大多数编程语言使用的哈希特拉格特拉格的基本技术描述在我转移到其他方面使用PowerShell之前使用了什么。

Hashtable是og体育与数组一样多的数据结构,除了使用密钥存储每个值(对象)。它是og体育基本的钥匙/价值存储。首先,我们创建og体育空的哈希表。

$ageList = @{}

请注意括号在定义上面定义数组时使用的括号。然后我们使用这样的键添加项目:

$key = 'Kevin'
$value = 36
$ageList.add( $key, $value )

$ageList.add( 'Alex', 9 )

这个人的名字是关键,他们的年龄是我想要保存的价值。

使用括号进行访问

将值添加到Hashtable后,您可以使用相同的键将它们拉退(而不是使用您对数组的数字索引)。

$ageList['Kevin']
$ageList['Alex']

当我想要凯文的年龄时,我用他的名字来访问它。 We can use this approach to add or update values into the hashtable too. This is just like using the add() function above.

$ageList = @{}

$key = 'Kevin'
$value = 36
$ageList[$key] = $value

$ageList['Alex'] = 9

还有另og体育语法,您可以用于访问和更新我将在后面的部分中介绍的值。如果您从另一种语言中发出PowerShell,则这些现有示例应该适合您之前可能使用过的哈希特。

使用值创建Hashtables

到目前为止,我刚刚为这些例子创建了og体育空的哈希特。创建它们时,可以预先填充键和值。

$ageList = @{
    Kevin = 36
    Alex  = 9
}

作为查找表

这种类型的Hashtable的实际值是您可以将它们用作查找表。这是og体育简单的例子。

$environments = @{
    Prod = 'SrvProd05'
    QA   = 'SrvQA02'
    Dev  = 'SrvDev12'
}

$server = $environments[$env]

In this example, you specify an environment for the $env variable and it will pick the correct server. You could use a switch($env){...} for something like this but this is a nice option.

This gets even better when you dynamically build the lookup table to use it later. So think about using this approach when you need to cross reference something. I think we would see this a lot more if Powershell was not so good at filtering on the pipe with Where-Object. If you are ever in a situation where performance matters, this is an approach that needs to be considered.

我不会说它更快,但它确实适应了 如果表现很重要,测试它.

多元化

通常,您将Hashtable视为键/值对,您可以提供og体育键并获得og体育值。 PowerShell允许您提供一系列键以获得多个值。

$environments[@('QA','DEV')]
$environments[('QA','DEV')]
$environments['QA','DEV']

在此示例中,我可以使用上面的相同查找,并提供3个不同的数组样式以获取匹配项。这是Powershell中的隐藏宝石,大多数人都不知道。

迭代Hashtables.

因为Hashtable是og体育密钥/值对的集合,所以您必须与数组或正常项目列表不同地迭代它。

首先要注意的是,如果你管道,那么管道将像og体育对象一样对待它。

PS:\> $ageList | Measure-Object
count : 1

Even though the .count property tells you how many values it contains.

PS:\> $ageList.count
2

You get around this issue by using the .values property if all you need is just the values.

PS:\> $ageList.values | Measure-Object -Average
Count   : 2
Average : 22.5

枚举键并使用它们访问值通常更有用。

PS:\> $ageList.keys | ForEach-Object{
        $message = '{0} is {1} years old!' -f $_, $ageList[$_]
        Write-Output $message
}
Kevin is 36 years old
Alex is 9 years old

Here is the same example with a foreach(){...} loop.

foreach($key in $ageList.keys)
{
    $message = '{0} is {1} years old' -f $key, $ageList[$key]
    Write-Output $message
}

我们正在哈希表中行走每个键,然后使用它来访问该值。在使用Hashtables作为集合时,这是og体育常见的模式。

GetEnumerator()

That brings us to GetEnumerator() for iterating over our hashtable.

$ageList.GetEnumerator() | ForEach-Object{
        $message = '{0} is {1} years old!' -f $_.key, $_.value
        Write-Output $message
}

枚举器陆续为您提供og体育键/值对。它专为此用例而设计。谢谢至 马克克劳斯 提醒我这个。

Badbumeration.

One important detail is that you cannot modify a hashtable while it is being enumerated. If we start with our basic $environments example:

$environments = @{
    Prod = 'SrvProd05'
    QA   = 'SrvQA02'
    Dev  = 'SrvDev12'
}

如果我们决定将每个服务器设置为相同的值,则会失败。

$environments.Keys | ForEach-Object {
    $environments[$_] = 'SrvDev03'
}

An error occurred while enumerating through a collection: Collection was modified; enumeration operation may not execute.
+ CategoryInfo          : InvalidOperation: tableEnumerator:HashtableEnumerator) [], RuntimeException
+ FullyQualifiedErrorId : BadEnumeration

即使看起来也应该没问题,这也会失败:

foreach($key in $environments.keys) {
    $environments[$key] = 'SrvDev03'
}

Collection was modified; enumeration operation may not execute.
    + CategoryInfo          : OperationStopped: (:) [], InvalidOperationException
    + FullyQualifiedErrorId : System.InvalidOperationException

这种情况的诀窍是在进行枚举之前克隆钥匙。

$environments.Keys.Clone() | ForEach-Object {
    $environments[$_] = 'SrvDev03'
}

Hashtable作为属性的集合

到目前为止,我们在我们的Hashtable中放置的物体类型都是相同类型的对象。我在所有这些例子中使用年龄,关键是该人的名字。当您的对象集合每个都有名称时,这是一种很好的方式。在PowerShell中使用Hashtables的另一种常用方法是持有一系列属性,其中密钥是属性的名称。在下og体育例子中,我将进入这个想法。

基于财产的访问

使用基于属性的访问更改了Hashtables的动态以及如何在PowerShell中使用它们。以下是我们通常的示例,从上面将键视为属性。

$ageList = @{}
$ageList.Kevin = 35
$ageList.Alex = 9

就像上面的示例一样,如果它们已经不存在,则会添加那些键。根据您定义的键以及您的值是什么,这是有点奇怪或完美的契合。年龄名单示例在这一点之前工作得很好。我们需要og体育新的榜样来觉得正确前进。

$person = @{
    name = 'Kevin'
    age  = 36
}

And we can add and access attributes on the $person like this.

$person.city = 'Austin'
$person.state = 'TX'

突然间,这种哈希特可以像对象一样开始感受。它仍然是一系列的东西,所以上面的所有例子仍然适用。我们只是从不同的角度逼近它。

检查键和值

在大多数情况下,您只需测试此值的值:

if( $person.age ){...}

It is simple but has been the source of many bugs for me because I was overlooking one important detail in my logic. I started to use it to test if a key was present. When the value was $false or zero, that statement would return $false unexpectedly.

if( $person.age -ne $null ){...}

这对零值的问题有关,但不是NULL VS不存在密钥。大多数时候,您不需要做出那种区别,但是当你这样做时都有功能。

if( $person.ContainsKey('age') ){...}

We also have a ContainsValue() for the situation where you need to test for a value without knowing the key or iterating the whole collection.

删除和清除键

You can remove keys with the .Remove() function.

$person.remove('age')

Assigning them a $null value just leaves you with a key that has a $null value.

清除哈哈斯特拉的常见方法是将它遗忘到空荡荡的哈希表。

$person = @{}

While that does work, try to use the clear() function instead.

$person.clear()

这是使用该函数创建自我记录代码的那些实例之一,并且它使代码的意图非常干净。

所有有趣的东西

订购的Hashtables.

By default, hashtables are not ordered (or sorted). In the traditional context, the order does not matter when you always use a key to access values. You may find that when using it to hold properties that you may want them to stay in the order that you define them. Thankfully, there is a way to do that with the ordered keyword.

$person = [ordered]@{
    name = 'Kevin'
    age  = 36
}

现在,当您枚举键和值时,他们将保持此顺序。

内联哈希特

当您在一行上定义Hashtable时,可以将键/值对与分号分隔。

$person = @{ name = 'kevin'; age = 36; }

如果您在管道上创建它们,这将派上用场。

公共流水线命令中的自定义表达式

There are a few cmdlets that support the use of hashtables to create custom or calculated properties. You will most commonly see this with Select-Object and Format-Table. The hashtables have a special syntax that looks like this when fully expanded.

$property = @{
    name = 'totalSpaceGB'
    expression = { ($_.used + $_.free) / 1GB }
}

The name is what the cmdlet would label that column. The expression is a script block that is executed where $_ is the value of the object on the pipe. Here is that script in action:

PS:\> $drives = Get-PSDrive | Where Used
PS:\> $drives | Select-Object -Properties name, $property

Name     totalSpaceGB
----     ------------
C    238.472652435303

I placed that in a variable but it could just as easily be defined inline and you can shorten name to n and expression to e while you are at it.

$drives | Select-Object -properties name, @{n='totalSpaceGB';e={($_.used + $_.free) / 1GB}}

I personally don’t like how long that makes commands and it often promotes some bad behaviors that I won’t get into. I am more likely to create a new hashtable or pscustomobject. with all the fields and properties that I want instead of using this approach in scripts. But there is a lot of code out there that does this so I wanted you to be aware of it. I talk about creating a pscustomobject. later on.

自定义排序表达式

It is easy to sort a collection if the objects have the data that you want to sort on. You can either add the data to the object before you sort it or create a custom expression for Sort-Object.

Get-ADUser | Sort-Object -Parameter @{ e={ Get-TotalSales $_.Name } }

在此示例中,我正在占用用户列表并使用某些自定义cmdlet获取其他信息。

对HASHTABLES列表进行排序

If you have a list of hashtables that you want to sort, you will find that the Sort-Object does not treat your keys as properties. We can get a round that by using a custom sort expressions.

$data = @(
    @{name='a'}
    @{name='c'}
    @{name='e'}
    @{name='f'}
    @{name='d'}
    @{name='b'}
)

$data | Sort-Object -Property @{e={$_.name}}

在cmdlets拆分Hashtables

这是我最喜欢的东西之一,许多人在很早就发现了很多人。这个想法是,而不是在一行上为cmdlet提供所有属性,而是可以先将它们包装到哈希表中。然后,您可以以特殊的方式向功能提供哈希表。以下是创建DHCP范围正常方式的示例。

Add-DhcpServerv4Scope -Name 'TestNetwork' -StartRange'10.0.0.2' -EndRange '10.0.0.254' -SubnetMask '255.255.255.0' -Description 'Network for testlab A' -LeaseDuration (New-TimeSpan -Days 8) -Type "Both"

不用使用 拆分,所有这些都需要在单行上定义。它要么滚下屏幕,要么会缠绕在何处。现在将其与使用拆分的命令进行比较。

$DHCPScope = @{
    Name        = 'TestNetwork'
    StartRange  = '10.0.0.2'
    EndRange    = '10.0.0.254'
    SubnetMask  = '255.255.255.0'
    Description = 'Network for testlab A'
    LeaseDuration = (New-TimeSpan -Days 8)
    Type = "Both"
}
Add-DhcpServerv4Scope @DHCPScope

The use of the @ sign instead of the $ is what invokes the splat operation.

只是花一点时间来欣赏这一例子是如何阅读。它们是具有所有相同值的完全相同的命令。第二个将更容易理解和维护前进。

我在任何时候使用splatting,命令过长。我定义了太长时间,因为导致我的窗口向右滚动。如果我为函数击中了3个属性,则赔率是我将使用Splatted Hashtable重写它。

拆分为可选参数

One of the most common ways I use spatting is to deal with optional parameters that come from someplace else in my script. Let’s say I have a function that wraps a Get-CIMInstance call that has an optional $Credential argument.

$CIMParams = @{
    ClassName = 'Win32_Bios'
    ComputerName = $ComputerName
}

if($Credential)
{
    $CIMParams.Credential = $Credential
}

Get-CIMInstance @CIMParams

I start by creating my hashtable with common parameters. Then I add the $Credential if it exists. Because I am using splatting here, I only need to have the call to Get-CIMInstance in my code once. This design pattern is very clean and can handle lots of optional parameters very easily.

To be fair, you could write your commands to allow $null values for parameters. You just don’t always have control over the other commands you are calling.

多个splats.

您可以将多个HASHTABLE SPLAT SPLAT到同一CMDLET。如果我们重新审视我们的原始拆分示例:

$Common = @{
    SubnetMask  = '255.255.255.0'
    LeaseDuration = (New-TimeSpan -Days 8)
    Type = "Both"
}

$DHCPScope = @{
    Name        = 'TestNetwork'
    StartRange  = '10.0.0.2'
    EndRange    = '10.0.0.254'
    Description = 'Network for testlab A'
}

Add-DhcpServerv4Scope @DHCPScope @Common

当我有og体育我传递给大量命令的常见参数集时,我会使用它。

分裂清洁代码

如果使您的代码清洁器拆分单个参数,则没有任何问题。

$log = @{Path = '.\logfile.log'}

Add-Content "logging this command" @log

拆分可执行文件

Splatting also works on some executables that use a /param:value syntax. Robocopy for example has some parameters like this.

$robo = @{R=1;W=1;MT=8}
robocopy source destination @robo

我不知道这就是所有的用途,但我发现它有趣。

添加Hashtables.

HASHTABLES支持添加opperator以组合两个HASHTABLES。

$person += @{Zip = '78701'}

这仅适用于两个Hashtables不共享密钥。

嵌套的哈希特

我们可以使用Hashtables作为Hashtable内的值。

$person = @{
    name = 'Kevin'
    age  = 36
}
$person.location = @{}
$person.location.city = 'Austin'
$person.location.state = 'TX'

I started with a basic hashtable containing 2 keys. I added a key called location with an empty hashtable. Then I added the last two items to that location hashtable. We can do this all inline too.

$person = @{
    name = 'Kevin'
    age  = 36
    location = @{
        city  = 'Austin'
        state = 'TX'
    }
}

这会创建与上面看到的相同的哈希表,可以同样访问该属性。

PS:> $person.location.city
Austin

有很多方法可以接近对象的结构。这是og体育查看嵌套散列的第二种方式。

$people = @{
    Kevin = @{
        age  = 36
        city = 'Austin'
    }
    Alex = @{
        age  = 9
        city = 'Austin'
    }
}

这将使用Hashtables作为对象集合的概念和属性集合。即使使用您喜欢的任何方法,也仍然易于访问。

PS:\> $people.kevin.age
36
PS:\> $people.kevin['city']
Austin
PS:\> $people['Alex'].age
9
PS:\> $people['Alex']['City']
Austin

当我像属性一样对待时,我倾向于使用DOT属性。这些通常是我在代码中静态定义的东西,我知道他们的头顶。如果我需要走该列表或以编程方式访问键,我将使用括号提供关键名。

foreach($name in $people.keys)
{
    $person = $people[$name]
    '{0}, age {1}, is in {2}' -f $name, $person.age, $person.city
}

具有嵌套Hashtables的能力为您提供了很多灵活性和选项。

看着嵌套的Hashtables

一旦您开始嵌套Hashtables,您将需要一种简单的方法来从控制台查看它们。如果我拍摄最后og体育哈希特,我会得到og体育看起来像这样的输出,它只会如此深:

ps:\> $people
Name                           Value
----                           -----
Kevin                          {age, city}
Alex                           {age, city}

My go to command for looking at these things is ConvertTo-JSON because it is very clean and I frequently use JSON on other things.

PS:\> $people | ConvertTo-JSON
{
    "Kevin":  {
                "age":  36,
                "city":  "Austin"
            },
    "Alex":  {
                "age":  9,
                "city":  "Austin"
            }
}

Even if you don’t know JSON, you should be able to see what you are looking for. There is a Format-Custom command for structured data like this but I still like the JSON view better.

创建对象

Sometimes you just need to have an object and using a hashtable to hold properties just is not getting the job done. Most commonly you want to see the keys as column names. A pscustomobject. makes that easy.

$person = [pscustomobject]@{
    name = 'Kevin'
    age  = 36
}

 PS:\> $person

name  age
----  ---
Kevin  36

Even if you don’t create it as a pscustomobject. initially, you can always cast it later when needed.

$person = @{
    name = 'Kevin'
    age  = 36
}

 PS:\> [pscustomobject]$person

name  age
----  ---
Kevin  36

我已经有很详细的写作 pscustomobject. 你应该在这个之后阅读。它在这里学到了很多东西。

保存到CSV.

Struggling with getting a hashtable to save to a CSV is one of the difficulties that I was referring to above. Convert your hashtable to a pscustomobject. and it will save correctly to CSV. It helps if you start with a pscustomobject. so the column order is preserved. But you can cast it to a pscustomobject. inline if needed.

$person | ForEach-Object{ [pscustomobject]$_ } | Export-CSV -Path $path

再次,查看我的写作 pscustomobject..

保存嵌套的Hashtable到文件

如果我需要将嵌套的Hashtable保存到文件,然后再次读取它,我使用JSON cmdlet来执行它。

$people | ConvertTo-JSON | Set-Content -Path $path
$people = Get-Content -Path $path -Raw | ConvertFrom-JSON

There are two important points about this method. First is that the JSON is written out multiline so I need to use the -Raw option to read it back into a single string. The Second is that the imported object is no longer a [hashtable]. It is now a [pscustomobject] and that can cause issues if you don’t expect it.

If you need it to be a [hashtable] on import, then you need to use the Export-CliXml and Import-CliXml commands.

将JSON转换为Hashtable

If you need to convert JSON to a [hashtable], there is one way that I know of to do it with the JavaScriptSerializer. in .Net.

[Reflection.Assembly]::LoadWithPartialName("System.Web.Script.Serialization")
$JSSerializer = [System.Web.Script.Serialization.JavaScriptSerializer]::new()
$JSSerializer.Deserialize($json,'Hashtable')

直接从文件读取

如果您有og体育包含PowerShell语法的Hashtable的文件,则有一种方法可以直接导入它。

$content = Get-Content -Path $Path -Raw -ErrorAction Stop
$scriptBlock = [scriptblock]::Create( $content )
$scriptBlock.CheckRestrictedLanguage( $allowedCommands, $allowedVariables, $true )
$hashtable = ( & $scriptBlock )

It imports the contents of the file into a scriptblock, then checks to make sure it does not have any other PowerShell commands in it before it executes it.

在那个注意事项上,您是否知道模块清单(PSD1文件)只是og体育哈希特?

钥匙只是字符串

我早些时候不想在这个切线上脱落,但钥匙只是琴弦。所以我们可以围绕任何东西引入并使其成为og体育关键。

$person = @{
    'full name' = 'Kevin Marquette'
    '#' = 3978
}
$person['full name']

你可以做一些奇怪的事情,你可能没有意识到你可以做到。

$person.'full name'

$key = 'full name'
$person.$key

只是因为你可以做点什么,这并不意味着你应该。最后og体育看起来像一只读你代码的人很容易被任何人轻易误解的错误。

从技术上讲,您的密钥不必是og体育字符串,但如果您只使用字符串,它们更容易考虑。

psboundparameters.

psboundparameters. 是og体育只存在于函数的上下文内的自动变量。它包含包含调用函数的所有参数。这不是og体育哈希表,但足够接近,你可以像og体育一样对待它。

这包括删除键并将其拆分给其他功能。如果您发现自己正在编写代理功能,请仔细看看这个。

about_automatic_variables. for more details.

psboundparameters. Gotcha

要记住的og体育重要措施是,这仅包括作为参数传递的值。如果您还有默认值的参数,但未通过调用者传递,则PSBoundParameters不包含这些值。这通常被忽视。

psdefaultparametervalual.

此自动变量允许您为任何cmdlet分配默认值而不更改cmdlet。看看这个例子。

$psdefaultparametervalual.["Out-File:Encoding"] = "UTF8"

This adds an entry to the $psdefaultparametervalual. hashtable that sets UTF8 as the default value for the Out-File -Encoding parameter. This is session specific so you should place it in your $profile.

我经常使用它来预先分配我经常键入的值。

$psdefaultparametervalual.[ "Connect-VIServer:Server" ] = 'VCENTER01.contoso.local'

这也接受通配符,因此您可以在批量中设置值。以下是您可以使用的方式:

$psdefaultparametervalual.[ "Get-*:Verbose" ] = $true
$psdefaultparametervalual.[ "*:Credential" ] = Get-Credental

对于更多的深度崩溃,看到这篇伟大的文章 自动默认值 经过 迈克尔斯蒂斯.

正则表达式$比赛

When you use the -match operator, an automatic variable called $matches is created with the results of the match. If you have any sub expressions in your regex, those sub matches are also listed.

$message = 'My SSN is 123-45-6789.'

$message -match 'My SSN is (.+)\.'
$Matches[0]
$Matches[1]

命名比赛

这是我最喜欢的功能之一,大多数人都不知道。如果您使用命名的Regex匹配,则可以通过匹配项中的名称访问该匹配。

$message = 'My Name is Kevin and my SSN is 123-45-6789.'

if($message -match 'My Name is (?<Name>.+) and my SSN is (?<SSN>.+)\.')
{
    $Matches.Name
    $Matches.SSN
}

In the example above, the (?<Name>.*) is a named sub expression. This value is then placed in the $Matches.Name property.

Group-object -ashashashtable

One little known feature of Group-Object is that it can turn some datasets into a hashtable for you.

Import-CSV $Path | Group-object -ashashashtable -Property email

这将每行添加到Hashtable中并使用指定的属性作为访问它的密钥。

数组是索引器

复制Hashtables.

重要的是要知道的是Hashtables是Objecs,每个变量只是对对象的引用。这只是意味着它需要更多的工作来制作有效的哈希表副本。

分配引用类型

当您有og体育Hashtable并将其分配给第二个变量时,两个变量都指向相同的哈希表。

PS> $orig = @{name='orig'}
PS> $copy = $orig
PS> $copy.name = 'copy'
PS> 'Copy: [{0}]' -f $copy.name
PS> 'Orig: [{0}]' -f $orig.name

Copy: [copy]
Orig: [copy]

这突出显示它们是相同的,因为更改og体育值的值也会改变另og体育值。将Hashtables传递到其他功能时,这也适用。如果这些函数对该具有更改进行更改,您的原件也会更改。

浅副本,单层

If we have a simple hashtable like our example above, we can use .Clone() to make a shallow copy.

PS> $orig = @{name='orig'}
PS> $copy = $orig.Clone()
PS> $copy.name = 'copy'
PS> 'Copy: [{0}]' -f $copy.name
PS> 'Orig: [{0}]' -f $orig.name

Copy: [copy]
Orig: [orig]

这将使我们能够对og体育不影响另og体育影响的基本更改。

浅副本,嵌套

它被称为浅副本的原因是因为它只会复制基础级别属性。如果其中og体育属性是引用类型(如另og体育Hashtable),那么那些嵌套对象仍将指向彼此。

PS> $orig = @{
        person=@{
            name='orig'
        }
    }
PS> $copy = $orig.Clone()
PS> $copy.person.name = 'copy'
PS> 'Copy: [{0}]' -f $copy.person.name
PS> 'Orig: [{0}]' -f $orig.person.name

Copy: [copy]
Orig: [copy]

So you can see that even though I cloned the hashtable, the reference to person was not cloned. We need to make a deep copy to truly have a second hashtable that is not linked to the first.

深副本

在撰写本文时,我不知道任何聪明的方式,可以让哈希表的深度副本(并将其保留为哈希表)。这只是一些需要写的事情之一。这是一种快速做到这一点的方法。

function Get-DeepClone
{
    [cmdletbinding()]
    param(
        $InputObject
    )
    process
    {
        if($InputObject -is [hashtable]) {
            $clone = @{}
            foreach($key in $InputObject.keys)
            {
                $clone[$key] = Get-DeepClone $InputObject[$key]
            }
            return $clone
        } else {
            return $InputObject
        }
    }
}

它没有处理任何其他reffernece类型或数组,但这是og体育很好的起点。

还要别的吗?

我很快弥补了很多地面。我的希望是,每次阅读这一点时,你都会走开一些新的东西或了解它。因为我涵盖了这个功能的全部频谱,所以有些方面只是可能不适用于你现在。这完全没问题,有点这取决于您与Powershell有多合作。

这是我们涵盖的一切列表,以防您想要跳回某些东西。通常情况下,这将在开始时进行,但这是从上到下写的,其中示例是在它之前的一切都有。