0

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

我有下面的脚本生成随机密码,我想使用生成的随机密码自动更新到我的 xml 中,每当我执行那个 powershell 脚本时。

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>
4

2 回答 2

3

这样的事情应该这样做:

$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 中,元素值中不允许有五个特殊字符。它们是<, &, >, 双引号"和单引号'

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

当您在文本编辑器中打开 XML 时,您可能会认为这些实体破坏了密码,并且如果下一个脚本或应用程序尝试使用正则表达式等文本方式解析 XML,那么它确实可以返回保存的密码,包括&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被“取消识别”到MP_jFmu0&sXBgEWcw中,就像您想要的那样。

于 2021-03-06T14:30:52.853 回答
2

为了增加@Theos 的好答案,我只是在探索替代模式和/或语法。不要接受这个答案,我只是想,既然我的工作方式不同,我不妨分享一下。

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

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

另一个区别是将 xPath 查询与Select-Xml.

Select-Xml或者,您可以使用以下.SelectSingleNode(...)方法跳过:

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

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

于 2021-03-06T19:04:26.210 回答