如何在 XML 中生成随机密码和更新

How to Generate Random Password & update in XML

拜托,我不擅长编写脚本,因此希望得到您的建议和支持。

我有以下生成随机密码的脚本,我想在每次执行该 powershell 脚本时使用自动更新到我的 xml 中的随机密码。

PowerShell 脚本--

$Password = New-Object -TypeName PSObject
$Password | Add-Member -MemberType ScriptProperty -Name "Password" -Value { ("!@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".tochararray() | sort {Get-Random})[0..16] -join '' }

XML文件内容--

<?xml version="1.0" encoding="UTF-8"?>
<BAPI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BAPI.xsd">
    <OPs Resource="https://XYZSevr:11231/api/Ops">
        <Password>ashdjaks723</Password>
    </OPs>
</BAPI>

应该这样做:

$xmlFile = "D:\Test\YourXmlFile.xml"   # put your file here
$xml = New-Object System.XML.XMLDocument
$xml.Load($xmlFile)

$pwChars = "!@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray()
$password = ($pwChars | Sort-Object {Get-Random})[0..16] -join ''

# set the password on the Password element inside the OPs element where it matches the Resource attribute
($xml.BAPI.OPs | Where-Object {$_.Resource -eq "https://XYZSevr:11231/api/Ops"}).Password = $password

# save the updated xml
$xml.Save($xmlFile)

关于 XML 特殊字符的简要说明,在本例中为 &

在XML中,元素值中不允许出现五个特殊字符。它们是 <&>、双引号 " 和单引号 '.

上面的代码自动保存包含这样一个字符的密码'entifies'这些字符变成resp。 &lt;&amp;&gt;&quot;&apos;。 在某些情况下,使用数字实体代替(如 & 变为 &#38;)。

当您在文本编辑器中打开 XML 时,您可能会认为这些实体破坏了密码,如果下一个脚本或应用程序尝试使用 文本解析 XML 意味着像正则表达式,那么它确实可以 return 保存的密码,包括 &amp;.
但是,如果使用 XML 的脚本在此方面按照 XML 规则播放,则无需担心,因为实体也会自动转换回它们所代表的字符。

让我们假设您保存的 XML 看起来像这样

<?xml version="1.0" encoding="UTF-8"?>
<BAPI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BAPI.xsd">
  <OPs Resource="https://XYZSevr:11231/api/Ops">
    <Password>MP_jFmu0&amp;sXBgEWcw</Password>
  </OPs>
</BAPI>

如您所见,& 字符在那里写为 &amp;

使用Powershell,像这样读回保存的密码:

$xmlFile = "D:\Test\YourXmlFile.xml"   # put your file here
$xml = New-Object System.XML.XMLDocument
$xml.Load($xmlFile)

$password = ($xml.BAPI.OPs | Where-Object {$_.Resource -eq "https://XYZSevr:11231/api/Ops"}).Password

$password

$password 中的结果值是 'de-entified' 到 MP_jFmu0&sXBgEWcw 中,正如您预期的那样。

为了扩充 ,我只是在探索替代模式 and/or 语法。不要接受这个答案,我只是想,既然我的计算方式不同,我不妨分享一下。

$XmlFile  = "C:\temp\yourXmlFile.xml"
$PwdChars = [Char[]](65..90 + 97..122 + 48..57) + [Char[]]"!@#$%^*_"
$Pass     = (Get-Random -InputObject $PwdChars -Count 16) -join ''
$XPath    = "/BAPI/OPs[@Resource='https://XYZSevr:11231/api/Ops']"

$Xml = [XML]::new()
$Xml.Load( $XmlFile )   
    
# Use Select-Xml cmdlet to change the password:
(Select-Xml -Xml $Xml -XPath $XPath).Node.PassWord = $Pass

# Save the updated XML:
$Xml.Save( $XmlFile )

以上我使用范围运算符来编译可接受字符的列表,而不是将它们键入。除了稍微更短或更细微的语法外,没有任何真正的好处。

另一个区别是使用带有 Select-Xml 的 xPath 查询。

您可以选择使用 .SelectSingleNode(...) 方法跳过 Select-Xml

$Xml.SelectSingleNode($XPath).Password = $Pass

您也可以直接用$xml.BAPI.OPs.Password = $Pass设置密码。在上面的示例中,除了通过 xPath 查询而不是 Where{} 子句实现外,我将其保留为有条件的。这种方法不区分大小写,而两种 xPath 方法都是。这是因为在第一种情况下是“.”。引用是 PowerShell 的一个特征,而 xPath 特定于 XML,它本身区分大小写。将 Where{} 子句与此结合使用将保持不区分大小写,再次因为 Where{} 是 PowerShell 而不是 XML.