【问题标题】:How to Generate Random Password & update in XML如何在 XML 中生成随机密码和更新
【发布时间】:2021-03-08 00:10:57
【问题描述】:

拜托,我不擅长编写脚本,因此寻求您的建议和支持。

我有以下生成随机密码的脚本,我想在执行该 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>

【问题讨论】:

  • 您能否更真实地表示您正在处理的 XML?我很想说您只需要深入了解元素并设置 innerText 属性。类似于This answer
  • 感谢 Steven,只是为了避免混淆,我刚刚更新了我想公开的行,但是根据您的建议,如果您现在可以提出建议,我已经更新了我的 xml。

标签: xml powershell automation script


【解决方案1】:

应该这样做:

$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 特殊字符,在本例中为 &amp;amp;

在 XML 中,元素值中不允许有五个特殊字符。它们是&amp;lt;&amp;amp;&amp;gt;、双引号"和单引号'

上面保存包含此类字符的密码的代码会自动将这些字符“识别”为相应的字符。 &amp;lt;&amp;amp;&amp;gt;&amp;quot;&amp;apos;。 在某些情况下,会使用数字实体(例如 &amp;amp; 变为 &amp;#38;)。

当您在文本编辑器中打开 XML 时,您可能会认为这些实体破坏了密码,并且如果下一个脚本或应用程序尝试使用 textual 解析 XML 意味着像正则表达式,那么它确实可以返回保存的密码,包括&amp;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;amp; 字符在那里写为&amp;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 中的结果值被“去识别”为 MP_jFmu0&amp;sXBgEWcw,正如您所期望的那样。

【讨论】:

  • 非常感谢 Theo,它按预期工作,但密码变得无效,如下所示 - w#YeKaRscWnXC&VH1 &不对
  • 知道了特殊字符“&”在生成密码时会产生问题,因此当我删除它时,它工作正常:-)
  • @Theo 很棒的补充。对角色很有帮助的东西。我可以问你为什么要排序吗?这是为了进一步降低可预测性吗?
  • @Steven 谢谢。排序是为了让字符以随机顺序使用,这确实使结果难以预测。
  • @Theo 等人。由于提到了使用 RegEx 解析 XML 文本,请查看来自 SO, RE: Parsing HTML with RegEx 的一位创始人的this blog post。我不排除它,这取决于任务,但是,这篇文章有点有趣。
【解决方案2】:

为了扩充@Theos great answer,我只是在探索替代模式和/或语法。不要接受这个答案,我只是想,既然我的解决方法不同,我不妨分享一下。

$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。

【讨论】:

    猜你喜欢
    • 2018-11-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2011-08-31
    相关资源
    最近更新 更多