遇到一个带有空值表达式的问题,我似乎无法弄明白。
该脚本应该更改<ComputerName>
文件中节点unattend.xml
的值,但会返回错误。
XML文件:
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SetupUILanguage>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
<InputLocale>0c09:00000409</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UILanguageFallback>en-US</UILanguageFallback>
<UserLocale>en-AU</UserLocale>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DiskConfiguration>
<Disk wcm:action="add">
<CreatePartitions>
<CreatePartition wcm:action="add">
<Order>1</Order>
<Type>Primary</Type>
<Size>100</Size>
</CreatePartition>
<CreatePartition wcm:action="add">
<Extend>true</Extend>
<Order>2</Order>
<Type>Primary</Type>
</CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<ModifyPartition wcm:action="add">
<Active>true</Active>
<Format>NTFS</Format>
<Label>System Reserved</Label>
<Order>1</Order>
<PartitionID>1</PartitionID>
<TypeID>0x27</TypeID>
</ModifyPartition>
<ModifyPartition wcm:action="add">
<Active>true</Active>
<Format>NTFS</Format>
<Label>OS</Label>
<Letter>C</Letter>
<Order>2</Order>
<PartitionID>2</PartitionID>
</ModifyPartition>
</ModifyPartitions>
<DiskID>0</DiskID>
<WillWipeDisk>true</WillWipeDisk>
</Disk>
</DiskConfiguration>
<ImageInstall>
<OSImage>
<InstallTo>
<DiskID>0</DiskID>
<PartitionID>2</PartitionID>
</InstallTo>
<InstallToAvailablePartition>false</InstallToAvailablePartition>
</OSImage>
</ImageInstall>
<UserData>
<AcceptEula>true</AcceptEula>
<FullName>Testuser</FullName>
<Organization></Organization>
</UserData>
<EnableFirewall>true</EnableFirewall>
</component>
</settings>
<settings pass="offlineServicing">
<component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<EnableLUA>false</EnableLUA>
</component>
</settings>
<settings pass="generalize">
<component name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SkipRearm>1</SkipRearm>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InputLocale>0c09:00000409</InputLocale>
<SystemLocale>en-AU</SystemLocale>
<UILanguage>en-AU</UILanguage>
<UILanguageFallback>en-AU</UILanguageFallback>
<UserLocale>en-AU</UserLocale>
</component>
<component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SkipAutoActivation>true</SkipAutoActivation>
</component>
<component name="Microsoft-Windows-SQMApi" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<CEIPEnabled>0</CEIPEnabled>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ComputerName>Test5-PC</ComputerName>
<ProductKey>W3GGN-FT8W3-Y4M27-J84CP-Q3VJ9</ProductKey>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AutoLogon>
<Password>
<Value></Value>
<PlainText>true</PlainText>
</Password>
<Enabled>true</Enabled>
<Username>Testuser</Username>
</AutoLogon>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Work</NetworkLocation>
<ProtectYourPC>1</ProtectYourPC>
<SkipUserOOBE>true</SkipUserOOBE>
<SkipMachineOOBE>true</SkipMachineOOBE>
</OOBE>
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Password>
<Value></Value>
<PlainText>true</PlainText>
</Password>
<Description></Description>
<DisplayName>Testuser</DisplayName>
<Group>Administrators</Group>
<Name>Testuser</Name>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<RegisteredOrganization></RegisteredOrganization>
<RegisteredOwner>Testuser</RegisteredOwner>
<DisableAutoDaylightTimeSet>false</DisableAutoDaylightTimeSet>
<TimeZone>AUS Eastern Standard Time</TimeZone>
<VisualEffects>
<SystemDefaultBackgroundColor>2</SystemDefaultBackgroundColor>
</VisualEffects>
</component>
<component name="Microsoft-Windows-ehome-reg-inf" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="NonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RestartEnabled>true</RestartEnabled>
</component>
<component name="Microsoft-Windows-ehome-reg-inf" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="NonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RestartEnabled>true</RestartEnabled>
</component>
</settings>
</unattend>
PowerShell脚本:
$ComputerName = "Test2-PC"
#Set ComputerName in unattend file
$filePath = "C:\unattend.xml"
[xml]$xml = Get-Content $filePath.TrimStart('"').TrimEnd('"')
$node = $xml.unattend | foreach settings | foreach component | foreach computername
$content = Get-Content -Path $filePath.TrimStart('"').TrimEnd('"')
$content | foreach {
$_.Replace($node.Trim(), $ComputerName)
} | Set-Content $filePath.TrimStart('"').TrimEnd('"')
错误是:
You cannot call a method on a null-valued expression. At line:1 char:1 + $node.Trim() + ~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull
键入$node
会将值显示为 Test5-PC ,因此会为其分配值。
运行:
if ($node -eq $null) {
Write-Host "is null"
} else {
Write-Host "is not null"
}
&#34>中的结果为空&#34;,所以它为空,但同时它有一个值?
从.Trim()
中删除$node.Trim()
会使脚本正常运行,但XML值不会在XML文件中更新。
我在这里缺少什么?
答案 0 :(得分:3)
您的XML文件中有11个<settings>
个节点,但其中只有一个节点具有嵌套节点<ComputerName>
。由于您的代码扩展了所有<settings>
个节点,然后尝试展开嵌套的<component>
和<ComputerName>
节点,最终会得到一个包含11个元素的数组,其中10个为$null
。您可以通过将$node
连接到这样的输出循环来验证这一点:
PS C:\> $node | ForEach-Object { "-$_-" } -- -- -- -- -- -- -- -Test5-PC- -- -- --
不要乱用字符串操作,而是正确使用PowerShell中内置的XML解析器。使用SelectSingleNode()
方法和XPath expression选择要修改的节点,更改其值,然后保存文件。
$ComputerName = "Test2-PC"
$filePath = "C:\unattend.xml"
[xml]$xml = Get-Content $filePath
$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$nsm.AddNamespace("ns", $xml.DocumentElement.NamespaceURI)
$node = $xml.SelectSingleNode("//ns:ComputerName", $nsm)
$node.'#text' = $ComputerName
$xml.Save($filePath)
请注意,此处需要命名空间管理器,因为您的XML文件使用命名空间(xmlns=...
)。另请注意,XPath表达式区分大小写,因此//ns:computername
将不起作用。你必须使用//ns:ComputerName
。
答案 1 :(得分:0)
您可以使用基于RegEx的-Replace
:
$ComputerName = "Test2-PC"
$filePath = ".\unattend.xml"
(Get-Content $filePath) -Replace "^<ComputerName>(.*?)</ComputerName>$","<ComputerName>$ComputerName</ComputerName>" | Set-Content $filePath
答案 2 :(得分:0)
通过将$ node指定为字符串来解决:
$ComputerName = "Test2-PC"
#Set ComputerName in unattend file
$filePath = "C:\unattend.xml"
[xml]$xml = Get-Content $filePath.TrimStart('"').TrimEnd('"')
[string]$node = $xml.unattend | foreach settings | foreach component | foreach computername
$content = Get-Content -Path $filePath.TrimStart('"').TrimEnd('"')
$content | foreach {
$_.Replace($node.Trim(), $ComputerName)
} | Set-Content $filePath.TrimStart('"').TrimEnd('"')