当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] PowerShell 哈希表 - 您需要了解的一切

作者:精品下载站 日期:2024-12-14 03:43:43 浏览:13 分类:玩电脑

PowerShell 哈希表 - 您需要了解的一切


PowerShell 中的哈希表可用于以结构化方式存储信息。这是通过使用键/值对来完成的,使您可以轻松地从哈希表中提取所需的信息。如果需要,您可以将 PowerShell 中的哈希表与关联数组进行比较。

哈希表在 PowerShell 中经常使用,因为它们是存储和处理信息的好方法。哈希表的伟大之处在于键和值可以是任何对象类型。因此,您不仅限于整数和字符串,还可以创建嵌套哈希表等。

在本文中,我们将了解哈希表以及如何在 PowerShell 脚本中使用它们。

哈希表与数组

在讨论哈希表之前,我们首先解释一下哈希表和数组之间的区别。这是一个经常被问到的问题,人们经常对两者感到困惑。

数组是值的索引列表。当您向数组添加值时,索引会自动生成。因此您无法控制在数组中存储信息的位置。

$array = @('apple','raspberry','kiwi')

我们可以通过循环访问数组中的项目或通过索引号访问项目:

$array | Foreach { Write-Host $_ }

# Result
apple
raspberry
kiwi

# Or by index number
write-host $array[1]

# Result
raspberry

我们还可以添加或更新数组中的值,但无法更改或确定项目的索引号:

# Replace the raspberry with melon
$array[1] = 'melon'

# Add a fruit to the array
$array += 'banana'

哈希表

正如我们所见,数组只是一个项目列表(集合),我们可以在列表中添加、修改或删除项目。当您向其中添加项目时,索引会自动生成。相反,对于 PowerShell HashTable,我们必须定义要添加的值的索引(键)。

为了创建哈希表,我们使用 {} 而不是 ()

# Creating a hashtable
$serverIps= @{}

# Or creating a pre-populate hashtable
$serverIps= @{
  'la-srv-lab02' = '192.168.10.2'
  'la-srv-db01' = '192.168.10.100'
}

要将服务器的 IP 地址添加到哈希表中,我们需要定义一个键。我们不能简单地执行$hashtable.add('value'),因为哈希表不会自动创建索引。

$key = 'la-srv-lab01'
$value = '192.168.10.1'
$serverIps.add($key,$value)

# Or simply
$serverIps.add('la-srv-lab03','192.168.10.3')

# Result:
$serverips

Name                           Value
----                           -----
la-srv-lab03                   192.168.10.3
la-srv-lab01                   192.168.10.1

本例中的关键是服务器名称和服务器的 IP 地址值。如果我们需要 lab03 服务器的 IP 地址,我们可以简单地执行以下操作:

从哈希表中检索数据

要从 PowerShell 中的哈希表检索数据,我们只需指定键,这将返回键的值:

$serverIps['la-srv-lab03']

# Result
192.168.10.3

另一种选择是迭代哈希表,但这与数组相比有点不同。如果我们只是简单地在哈希表后面传递一个 foreach,您会注意到它只返回一个哈希表对象:

$serverIps | foreach {write-host $_}
System.Collections.Hashtable

要仅从哈希表中获取值,我们可以使用 .value 属性:

# Return only the values
$serverIps.values

# Or pipe them in a foreach to ping the servers for example:
$serverIps.values | foreach {ping $_}

使用哈希表时,您可能还希望以键/值对的形式检索数据。为此,我们可以使用 GetEnumerator 函数:

$serverIps.GetEnumerator() | ForEach-Object {
   $result = '{0} IP address is {1}' -f $_.key, $_.value
   write-host $result
}

# Result
la-srv-lab03 IP address is 192.168.10.3
la-srv-lab01 IP address is 192.168.10.1

更新值

可以通过使用键选择正确的键/值对来更新哈希表中的值:

$serverIps['la-srv-lab03'] = '192.168.10.5'

如果需要更新哈希表中的多个值,则不能简单地使用 ForEach 循环来迭代哈希表。例如,这是行不通的:

$serverIps.Keys | ForEach-Object {
    $serverIps[$_] = '192.168.10.20'
}

您首先需要克隆密钥,然后才能更新值:

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

删除键或值

要从哈希表中完全删除键/值对,您可以使用 .remove 函数。您需要指定要删除的密钥:

$serverIps.Remove('la-srv-lab03')

也可以只删除键中的值:

$serverIps['la-srv-lab03'] = $null

要完全清除哈希表,您有两种选择:重新创建哈希表实例或使用清除函数。后者是首选,因为它使您的代码更易于阅读。

# Recreate the hashtable instance
$serverIps = @{}

# Better option for readability, use the clear function
$serverIps.clear()

散列表

PowerShell 中的一些 cmdlet 需要很多属性,我们通常都将这些属性写在一行上。这可能会使您的 PowerShell 脚本难以阅读,因为您可能需要水平滚动才能查看完整的命令。

例如,当您想从 PowerShell 发送电子邮件时,您最终会得到一长行参数

Send-MailMessage -SmtpServer smtp.contoso.com -To [email protected] -From [email protected] -Subject 'super long subject goes here' -Body 'Test email from PowerShell' -Priority High

为了使其更具可读性,我们可以使用哈希表并将其打散。展开用单个变量替换所有参数和值。请注意,我们使用 @ 符号来展开变量,而不是 $

$mail = @{
  SmtpServer  = 'smtp.contoso.com'
  To          = '[email protected]'
  From        = '[email protected]'
  Subject     = 'super long subject goes here'
  Body        = 'Test email from PowerShell'
  Priority    = High
}

# Note the @ infront of mail, instead of $
Send-MailMessage @mail

正如您所看到的,splatting 使您的代码更易于阅读和维护,而不是一长串参数。

从哈希表创建对象

当您需要为单个对象或展开数据构建数据时,哈希表非常有用,但它们不是真正的对象。哈希表只有两列:键和值。因此,我们可以使用单个服务器的规格创建哈希表,但是当我们需要存储有关多个服务器的数据时,我们会遇到限制(例如,我们无法重用列名)。

因此,当您有多个条目时,构建数据的更好方法是使用对象。在 PowerShell 中创建对象的最简单方法是将哈希表转换为自定义 PowerShell 对象。我们通过在哈希表前面添加 [pscustomobject] 来实现此目的。

拿下面的例子来说,首先我们创建一个带有服务器规范的哈希表:

$servers = @{
  'name'    = 'la-srv-db01'
  'ip'      = '192.168.10.100'
  'model'   = 'Hp DL380 G10'
  'memory'  = '96Gb'
}

# Result
Name                           Value
----                           -----
memory                         96Gb
ip                             192.168.10.100
name                           la-srv-db01
model                          Hp DL380 G10

如您所见,我们只有两列:名称和值。哈希表代表单个服务器,我们不能使用它来创建服务器列表。

但是,如果我们将哈希表转换为自定义 PowerShell 对象,我们会得到一个实际的表,其中有多个列。

$servers = [pscustomobject]@{
  'name'    = 'la-srv-db01'
  'ip'      = '192.168.10.100'
  'model'   = 'Hp DL380 G10'
  'memory'  = '96Gb'
}

# Result
name        ip             model        memory
----        --             -----        ------
la-srv-db01 192.168.10.100 Hp DL380 G10 96Gb  

现在我们也可以向 pscustomobject 添加另一个服务器:

function servers {
  [pscustomobject]@{
    'name'    = 'la-srv-db01'
    'ip'      = '192.168.10.100'
    'model'   = 'Hp DL380 G10'
    'memory'  = '96Gb'  
  }
  [pscustomobject]@{
    'name'    = 'la-srv-lab03'
    'ip'      = '192.168.10.3'
    'model'   = 'Hp DL180 G9'
    'memory'  = '32Gb'
  }
}

servers

# Result
name         ip             model        memory
----         --             -----        ------
la-srv-db01  192.168.10.100 Hp DL380 G10 96Gb
la-srv-lab03 192.168.10.3   Hp DL180 G9  32Gb

将哈希表导出为 CSV

当您将哈希表导出到 CSV 时,您会注意到默认情况下不会导出键和值。输出将仅包含有关哈希表对象的信息,而不包含哈希表内的数据。

要实际导出哈希表的内容,您需要使用 GetEnumerator 方法,就像我们查看哈希表的内容一样。我们只需要哈希表中的键和值,因此您还需要向命令添加一个选择。

$serverIps= @{
  'la-srv-lab02' = '192.168.10.2'
  'la-srv-db01' = '192.168.10.100'
  'la-srv-lab03' = '192.168.10.3'
}

$serverIps.GetEnumerator() | Select Key, Value | Export-CSV -path c:\temp\hash.csv -No

[玩转系统] PowerShell 哈希表 - 您需要了解的一切

总结

PowerShell 中的哈希表是构建数据或与展开结合使用的好方法。但是,请记住,它们仅用于单个项目。我们无法创建自定义列或使用相同的键存储多行。为此,您确实需要使用自定义 PowerShell 对象。

我希望这篇文章对您有用,如果您有任何疑问,请在下面发表评论。

如果您想了解有关 PowerShell 的更多信息,请确保您还阅读了您必须了解的 10 个 PowerShell 命令

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯