1

使用 Splatting Hashtable 设置参数并且效果很好。我传递给一个函数New-ADUser @param,在 splatting 中设置的值将在 Active Directory 中创建。但是,我的脚本将在其他地方运行。Json 文件将由用户操作。

我如何New-ADUser @param将 Json 文件而不是 Splatting table 传递给此函数。

谢谢你的帮助。

4

2 回答 2

2

注意:以下假设您的 JSON 配置文件:

  • 包含一个对象,其属性名称与目标 cmdlet的参数名称匹配,New-ADUser
  • 并且属性仅限于字符串、数字、布尔值和嵌套对象,PowerShell 可以根据此答案中解释的约束将其强制转换为参数的类型。

这些约束确保该对象的哈希表表示可以按原样用于参数喷射


如果您正在运行PowerShell (Core) 7+,则可以利用ConvertFrom-Json's
-AsHashtableparameter

# Load JSON from file 'config.json' into a [hashtable] instance.
$params = Get-Content -Raw config.json | ConvertFrom-Json -AsHashtable

# Use the hashtable for splatting.
New-ADUser @params

Windows PowerShell(其最新和最终版本是 5.1)中,您必须手动[pscustomobject]返回的实例转换ConvertFrom-Json hashtable

# Load JSON from file 'config.json' into a [pscustomobject] instance.
$paramsAux = Get-Content -Raw config.json | ConvertFrom-Json

# Convert the [pscustomobject] to a [hashtable] instance by 
# making its properties (name-value pairs) hashtable entries.
$params = @{}
foreach ($prop in $paramsAux.psobject.Properties) {
  $params[$prop.Name] = $prop.Value
}

# Use the hashtable for splatting.
New-ADUser @params

您在评论中提供的示例配置 JSON 表明不满足顶部所述的先决条件并且需要对配置 JSON 进行自定义转换才能映射到目标New-ADUser参数:

  • 更新:真正预期的目标 cmdlet 原来是,其参数与下面New-AzureADuser示例 JSON 的属性直接匹配,因此不需要自定义转换;希望所展示的技术对需要自定义转换的未来读者仍然有用。
# Create a sample JSON config file.
@'
{
  "GivenName": "Lili",
  "SurName": "Waters",
  "accountEnabled": true,
  "displayName": "Lili Waters",
  "mailNickname": "LiliW",
  "userPrincipalName": "liliw@mailcom",
  "passwordProfile": {
    "forceChangePasswordNextSignIn": true,
    "password": "xxyyzz"
  }
}
'@ > config.json

# Load JSON from file 'config.json' into a [pscustomobject] instance.
$paramsAux = Get-Content -Raw config.json | ConvertFrom-Json

# Convert the [pscustomobject] to a [hashtable] instance by 
# making its properties (name-value pairs) hashtable entries,
# applying custom transformations, as necessary.
$params = @{}
foreach ($prop in $paramsAux.psobject.Properties) {
  switch ($prop.Name) {
    # Map the JSON property names and values onto the appropriate 
    # New-ADUser parameters.
    'accountEnabled'  { $params['Enabled'] = $prop.Value }

    'mailNickname'    { $params['SamAccountName'] = $prop.Value  }

    'passwordProfile' { 
      $params['ChangePasswordAtLogon'] = $prop.Value.forceChangePasswordNextSignIn
      $params['AccountPassword'] = ConvertTo-SecureString -Force -AsPlainText $prop.Value.password
     }

    # All other properties directly map onto New-ADUser parameters.
    default           { $params[$prop.Name] = $prop.Value }
  }
}

# Use the hashtable for splatting.
# Note: To inspect the actual arguments being passed, use Write-Output in lieu
#       of New-ADUser, or just output the hashtable, $params, by itself.
New-ADUser @params

注意:我不确定mailNickname属性映射到什么参数;我在上面假设过-SamAccountName;根据需要进行调整。

于 2021-07-12T19:05:19.967 回答
0

@mklement0 的回答很好,解释了一切。我目前被困在 ps5 世界中,所以我不得不求助于跳过 -ashashtable 选项。我想我会展示一个小例子来说明我是如何做到的。这只是 @mklement0 的一个更简洁的版本。

我目前使用 oneliner 进行转换,如下面的 sql 示例:

#get all my settings
$cfg = Get-Content settings.json -Raw | ConvertFrom-Json

#convert the arguments i want to splat
$sqlargs = $cfg.sql.psobject.Properties|%{$h=@{}}{$h."$($_.Name)"=$_.Value}{$h}

#use args as splat
$dt = Invoke-Sqlcmd @sqlargs

和 settings.json 看起来像......

{
    "sql": {
        "QueryTimeout": 1800,
        "ConnectionString": "my connection string",
        "InputFile": "sqlfile.sql",
        "OutputAs": "DataTables"
    }
}

我在文件中有其他设置不需要作为 args 传递,所以我不需要转换整个文件,只需这个属性即可。

我考虑过为此创建一个模块,因为我将它用于各种事情,但我这个项目看起来在这种情况下可以解决问题。

于 2021-10-07T19:59:54.937 回答