github.com/cloudfoundry-incubator/stembuild@v0.0.0-20211223202937-5b61d62226c6/modules/BOSH.Sysprep/BOSH.Sysprep.psm1 (about)

     1  <#
     2  .Synopsis
     3    Sysprep Utilities
     4  .Description
     5    This cmdlet enables enabling a local security policy for a stemcell
     6  #>
     7  function Enable-LocalSecurityPolicy {
     8    Param (
     9      [string]$PolicySource =$(throw "Policy backup filepath is required")
    10    )
    11    Write-Log "Starting LocalSecurityPolicy"
    12  
    13    # Convert registry.txt files into registry.pol files
    14    $MachineDir="$PolicySource/DomainSysvol/GPO/Machine"
    15    LGPO.exe /r "$MachineDir/registry.txt" /w "$MachineDir/registry.pol"
    16    if ($LASTEXITCODE -ne 0) {
    17      Write-Error "Generating policy: Machine"
    18    }
    19  
    20    $UserDir="$PolicySource/DomainSysvol/GPO/User"
    21    LGPO.exe /r "$UserDir/registry.txt" /w "$UserDir/registry.pol"
    22    if ($LASTEXITCODE -ne 0) {
    23      Write-Error "Generating policy: User"
    24    }
    25  
    26    # Apply policies
    27    LGPO.exe /g "$PolicySource/DomainSysvol" /v
    28    if ($LASTEXITCODE -ne 0) {
    29      Write-Error "Applying policy: $PolicySource/DomainSysvol"
    30    }
    31  
    32    Write-Log "Ending LocalSecurityPolicy"
    33  }
    34  
    35  <#
    36  .Synopsis
    37    Sysprep Utilities
    38  .Description
    39    This cmdlet creates the Unattend file for sysprep
    40  #>
    41  function Create-Unattend {
    42    Param (
    43      [string]$UnattendDestination = "C:\Windows\Panther\Unattend",
    44      [string]$NewPassword,
    45      [string]$ProductKey,
    46      [string]$Organization,
    47      [string]$Owner
    48    )
    49    Write-Log "Starting Create-Unattend"
    50  
    51    New-Item -ItemType directory $UnattendDestination -Force
    52    $UnattendPath = Join-Path $UnattendDestination "unattend.xml"
    53  
    54    Write-Log "Writing unattend.xml to $UnattendPath"
    55  
    56    $ProductKeyXML=""
    57    if ($ProductKey -ne "") {
    58      $ProductKeyXML="<ProductKey>$ProductKey</ProductKey>"
    59    }
    60  
    61    $OrganizationXML="<RegisteredOrganization />"
    62    if ($Organization -ne "" -and $Organization -ne $null) {
    63      $OrganizationXML="<RegisteredOrganization>$Organization</RegisteredOrganization>"
    64    }
    65  
    66    $OwnerXML="<RegisteredOwner />"
    67    if ($Owner -ne "" -and $Owner -ne $null) {
    68      $OwnerXML="<RegisteredOwner>$Owner</RegisteredOwner>"
    69    }
    70  
    71    $AdministratorPasswordXML = ""
    72    if ($NewPassword -ne "" -and $NewPassword -ne $null) {
    73      $NewPassword = [system.convert]::ToBase64String([system.text.encoding]::Unicode.GetBytes($NewPassword + "AdministratorPassword"))
    74      $AdministratorPasswordXML = @"
    75        <UserAccounts>
    76          <AdministratorPassword>
    77            <Value>$NewPassword</Value>
    78            <PlainText>false</PlainText>
    79          </AdministratorPassword>
    80        </UserAccounts>
    81  "@
    82    }
    83  
    84    $PostUnattend = @"
    85  <?xml version="1.0" encoding="utf-8"?>
    86  <unattend xmlns="urn:schemas-microsoft-com:unattend">
    87    <settings pass="specialize">
    88      <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
    89        <OEMInformation>
    90          <HelpCustomized>false</HelpCustomized>
    91        </OEMInformation>
    92        <ComputerName>*</ComputerName>
    93        <TimeZone>UTC</TimeZone>
    94        $ProductKeyXML
    95        $OrganizationXML
    96        $OwnerXML
    97      </component>
    98      <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
    99        <DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon>
   100      </component>
   101      <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-OutOfBoxExperience" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
   102        <DoNotOpenInitialConfigurationTasksAtLogon>true</DoNotOpenInitialConfigurationTasksAtLogon>
   103      </component>
   104      <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
   105        <SkipAutoActivation>true</SkipAutoActivation>
   106      </component>
   107      <component name="Microsoft-Windows-NetBT" 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">
   108          <Interfaces>
   109              <Interface wcm:action="add">
   110                  <NetbiosOptions>2</NetbiosOptions>
   111                  <Identifier>Ethernet0</Identifier>
   112              </Interface>
   113          </Interfaces>
   114      </component>
   115    </settings>
   116    <settings pass="generalize">
   117      <component name="Microsoft-Windows-PnpSysprep" 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">
   118        <PersistAllDeviceInstalls>false</PersistAllDeviceInstalls>
   119        <DoNotCleanUpNonPresentDevices>false</DoNotCleanUpNonPresentDevices>
   120      </component>
   121    </settings>
   122    <settings pass="oobeSystem">
   123      <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">
   124        <InputLocale>en-US</InputLocale>
   125        <SystemLocale>en-US</SystemLocale>
   126        <UILanguage>en-US</UILanguage>
   127        <UserLocale>en-US</UserLocale>
   128      </component>
   129      <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">
   130        <OOBE>
   131          <HideEULAPage>true</HideEULAPage>
   132          <ProtectYourPC>3</ProtectYourPC>
   133          <NetworkLocation>Home</NetworkLocation>
   134          <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
   135        </OOBE>
   136        <TimeZone>UTC</TimeZone>
   137        $AdministratorPasswordXML
   138      </component>
   139    </settings>
   140  </unattend>
   141  "@
   142  
   143    Out-File -FilePath $UnattendPath -InputObject $PostUnattend -Encoding utf8
   144  }
   145  
   146  <#
   147  .Synopsis
   148    Sanity check that the unattend.xml shipped with GCP has not changed.
   149  .Description
   150    Sanity check that the unattend.xml shipped with GCP has not changed.
   151  #>
   152  function Check-Default-GCP-Unattend() {
   153  
   154    [xml]$Expected = @'
   155  <?xml version="1.0" encoding="utf-8"?>
   156  <unattend xmlns="urn:schemas-microsoft-com:unattend">
   157    <!--
   158    For more information about unattended.xml please refer too
   159    http://technet.microsoft.com/en-us/library/cc722132(v=ws.10).aspx
   160    -->
   161    <settings pass="generalize">
   162      <component name="Microsoft-Windows-PnpSysprep" 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">
   163        <PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
   164      </component>
   165    </settings>
   166    <settings pass="specialize">
   167      <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">
   168        <!-- Random ComputerName, will be replaced by specialize script -->
   169        <ComputerName></ComputerName>
   170        <TimeZone>Greenwich Standard Time</TimeZone>
   171      </component>
   172    </settings>
   173    <settings pass="oobeSystem">
   174      <!-- Setting Location Information -->
   175      <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">
   176        <InputLocale>en-us</InputLocale>
   177        <SystemLocale>en-us</SystemLocale>
   178        <UILanguage>en-us</UILanguage>
   179        <UserLocale>en-us</UserLocale>
   180      </component>
   181      <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">
   182        <OOBE>
   183          <!-- Setting EULA -->
   184          <HideEULAPage>true</HideEULAPage>
   185          <!-- Setting network location to public -->
   186          <NetworkLocation>Other</NetworkLocation>
   187          <!-- Hide Wirelss setup -->
   188          <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
   189          <ProtectYourPC>1</ProtectYourPC>
   190          <SkipMachineOOBE>true</SkipMachineOOBE>
   191          <SkipUserOOBE>true</SkipUserOOBE>
   192        </OOBE>
   193        <!-- Setting timezone to GMT -->
   194        <ShowWindowsLive>false</ShowWindowsLive>
   195        <TimeZone>Greenwich Standard Time</TimeZone>
   196        <!--Setting OEM information -->
   197        <OEMInformation>
   198          <Manufacturer>Google Cloud Platform</Manufacturer>
   199          <Model>Google Compute Engine Virtual Machine</Model>
   200          <SupportURL>https://support.google.com/enterprisehelp/answer/142244?hl=en#cloud</SupportURL>
   201          <Logo>C:\Program Files\Google Compute Engine\sysprep\gcp.bmp</Logo>
   202        </OEMInformation>
   203      </component>
   204    </settings>
   205  </unattend>
   206  '@
   207  
   208    $UnattendPath = "C:\Program Files\Google\Compute Engine\sysprep\unattended.xml"
   209    [xml]$Unattend = (Get-Content -Path $UnattendPath)
   210  
   211    if (-Not ($Unattend.xml.Equals($Expected.xml))) {
   212    Write-Error "The unattend.xml shipped with GCP has changed."
   213    }
   214  }
   215  
   216  function Create-Unattend-GCP() {
   217    Param (
   218      [string]$UnattendDestination = "C:\Program Files\Google\Compute Engine\sysprep"
   219    )
   220    $UnattendXML = @'
   221  <?xml version="1.0" encoding="utf-8"?>
   222  <unattend xmlns="urn:schemas-microsoft-com:unattend">
   223    <!--
   224    For more information about unattended.xml please refer too
   225    http://technet.microsoft.com/en-us/library/cc722132(v=ws.10).aspx
   226    -->
   227    <settings pass="generalize">
   228      <component name="Microsoft-Windows-PnpSysprep" 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">
   229        <PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
   230      </component>
   231    </settings>
   232    <settings pass="specialize">
   233      <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">
   234        <!-- Random ComputerName, will be replaced by specialize script -->
   235        <ComputerName></ComputerName>
   236        <TimeZone>UTC</TimeZone>
   237      </component>
   238    </settings>
   239    <settings pass="oobeSystem">
   240      <!-- Setting Location Information -->
   241      <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">
   242        <InputLocale>en-us</InputLocale>
   243        <SystemLocale>en-us</SystemLocale>
   244        <UILanguage>en-us</UILanguage>
   245        <UserLocale>en-us</UserLocale>
   246      </component>
   247      <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">
   248        <OOBE>
   249          <!-- Setting EULA -->
   250          <HideEULAPage>true</HideEULAPage>
   251          <!-- Setting network location to public -->
   252          <NetworkLocation>Other</NetworkLocation>
   253          <!-- Hide Wirelss setup -->
   254          <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
   255          <ProtectYourPC>3</ProtectYourPC>
   256          <SkipMachineOOBE>true</SkipMachineOOBE>
   257          <SkipUserOOBE>true</SkipUserOOBE>
   258        </OOBE>
   259        <!-- Setting timezone to GMT -->
   260        <ShowWindowsLive>false</ShowWindowsLive>
   261        <TimeZone>UTC</TimeZone>
   262        <!--Setting OEM information -->
   263        <OEMInformation>
   264          <Manufacturer>Google Cloud Platform</Manufacturer>
   265          <Model>Google Compute Engine Virtual Machine</Model>
   266          <SupportURL>https://support.google.com/enterprisehelp/answer/142244?hl=en#cloud</SupportURL>
   267          <Logo>C:\Program Files\Google Compute Engine\sysprep\gcp.bmp</Logo>
   268        </OEMInformation>
   269      </component>
   270    </settings>
   271  </unattend>
   272  '@
   273  
   274    $UnattendPath = Join-Path $UnattendDestination "unattended.xml"
   275  
   276    Out-File -FilePath $UnattendPath -InputObject $UnattendXML -Encoding utf8 -Force
   277  }
   278  
   279  function Remove-WasPassProcessed {
   280    Param (
   281      [string]$AnswerFilePath
   282    )
   283  
   284    If (!$(Test-Path $AnswerFilePath)) {
   285      Throw "Answer file $AnswerFilePath does not exist"
   286    }
   287  
   288    Write-Log "Removing wasPassProcessed"
   289  
   290    $content = [xml](Get-Content $AnswerFilePath)
   291  
   292    foreach ($specializeBlock in $content.unattend.settings) {
   293      $specializeBlock.RemoveAttribute("wasPassProcessed")
   294    }
   295  
   296    $content.Save($AnswerFilePath)
   297  }
   298  
   299  function Remove-UserAccounts {
   300    Param (
   301      [string]$AnswerFilePath
   302    )
   303  
   304    If (!$(Test-Path $AnswerFilePath)) {
   305      Throw "Answer file $AnswerFilePath does not exist"
   306    }
   307  
   308    Write-Log "Removing UserAccounts block from Answer File"
   309  
   310    $content = [xml](Get-Content $AnswerFilePath)
   311    $mswShellSetup =  (($content.unattend.settings|where {$_.pass -eq 'oobeSystem'}).component|where {$_.name -eq "Microsoft-Windows-Shell-Setup"})
   312  
   313    if ($mswShellSetup -eq $Null) {
   314      Throw "Could not locate oobeSystem XML block. You may not be running this function on an answer file."
   315    }
   316  
   317    $userAccountsBlock = $mswShellSetup.UserAccounts
   318  
   319    if ($userAccountsBlock.Count -eq 0) {
   320      Return
   321    }
   322  
   323    $mswShellSetup.RemoveChild($userAccountsBlock)
   324  
   325    $content.Save($AnswerFilePath)
   326  }
   327  
   328  function Update-AWS2012R2Config {
   329    $ec2config = [xml] (get-content 'C:\Program Files\Amazon\Ec2ConfigService\Settings\config.xml')
   330  
   331    # Enable password generation and retrieval
   332    ($ec2config.ec2configurationsettings.plugins.plugin | where { $_.Name -eq "Ec2SetPassword" }).State = 'Enabled'
   333  
   334    # Disable SetDnsSuffixList setting
   335    $ec2config.ec2configurationsettings.GlobalSettings.SetDnsSuffixList = "false"
   336  
   337    $ec2config.Save("C:\Program Files\Amazon\Ec2ConfigService\Settings\config.xml")
   338  
   339    # Enable sysprep
   340    $ec2settings = [xml] (get-content 'C:\Program Files\Amazon\Ec2ConfigService\Settings\BundleConfig.xml')
   341    ($ec2settings.BundleConfig.Property | where { $_.Name -eq "AutoSysprep" }).Value = 'Yes'
   342  
   343    # Don't shutdown when running sysprep, let packer do it
   344    # ($ec2settings.BundleConfig.GeneralSettings.Sysprep | where { $_.AnswerFilePath -eq "sysprep2008.xml" }).Switches = "/oobe /quit /generalize"
   345  
   346    $ec2settings.Save('C:\Program Files\Amazon\Ec2ConfigService\Settings\BundleConfig.xml')
   347  }
   348  
   349  function Update-AWS2016Config
   350  {
   351    $LaunchConfigJson = 'C:\ProgramData\Amazon\EC2-Windows\Launch\Config\LaunchConfig.json'
   352    $LaunchConfig = Get-Content $LaunchConfigJson -raw | ConvertFrom-Json
   353    $LaunchConfig.addDnsSuffixList = $False
   354    $LaunchConfig.extendBootVolumeSize = $False
   355    $LaunchConfig | ConvertTo-Json | Set-Content $LaunchConfigJson
   356  }
   357  
   358  function Enable-AWS2016Sysprep {
   359    # Enable sysprep
   360    cd 'C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts'
   361    ./InitializeInstance.ps1 -Schedule
   362    ./SysprepInstance.ps1
   363  }
   364  
   365  <#
   366  .Synopsis
   367    Sysprep Utilities
   368  .Description
   369    This cmdlet runs Sysprep and generalizes a VM so it can be a BOSH stemcell
   370  #>
   371  function Invoke-Sysprep()
   372  {
   373    Param (
   374      [string]$IaaS = $( Throw "Provide the IaaS this stemcell will be used for" ),
   375      [string]$NewPassword,
   376      [string]$ProductKey = "",
   377      [string]$Organization = "",
   378      [string]$Owner = "",
   379      [switch]$SkipLGPO,
   380      [switch]$EnableRDP
   381    )
   382  
   383    Write-Log "Invoking Sysprep for IaaS: ${IaaS}"
   384  
   385    $OsVersion = Get-OSVersion
   386  
   387    # WARN WARN: this should be removed when Microsoft fixes this bug
   388    # See tracker story https://www.pivotaltracker.com/story/show/150238324
   389    # Skip sysprep if using Windows Server 2016 insider build with UALSVC bug
   390    $RegPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"
   391    If ((Get-ItemProperty -Path $RegPath).CurrentBuildNumber -Eq '16278')
   392    {
   393      Stop-Computer
   394    }
   395  
   396    Allow-NTPSync
   397  
   398    if (-Not $SkipLGPO)
   399    {
   400      if (-Not (Test-Path "C:\Windows\LGPO.exe")) {
   401        Throw "Error: LGPO.exe is expected to be installed to C:\Windows\LGPO.exe"
   402      }
   403  
   404      switch ($OsVersion)
   405      {
   406        "windows2012R2" {
   407          Enable-LocalSecurityPolicy (Join-Path $PSScriptRoot "cis-merge-2012R2")
   408        }
   409  
   410        "windows1803" {
   411          Enable-LocalSecurityPolicy (Join-Path $PSScriptRoot "cis-merge-1803")
   412        }
   413  
   414        "windows2019" {
   415          Enable-LocalSecurityPolicy (Join-Path $PSScriptRoot "cis-merge-2019")
   416        }
   417      }
   418    }
   419  
   420    switch ($IaaS) {
   421      "aws" {
   422        switch ($OsVersion) {
   423          "windows2012R2" {
   424            Update-AWS2012R2Config
   425            Start-Process "C:\Program Files\Amazon\Ec2ConfigService\Ec2Config.exe" -ArgumentList "-sysprep" -Wait
   426          }
   427          {($_ -eq"windows2016") -or ($_ -eq"windows1803") -or ($_ -eq"windows2019")} {
   428            Update-AWS2016Config
   429            Enable-AWS2016Sysprep
   430          }
   431        }
   432      }
   433      "gcp" {
   434        Create-Unattend-GCP
   435        GCESysprep
   436      }
   437      "azure" {
   438        C:\Windows\System32\Sysprep\sysprep.exe /generalize /quiet /oobe /quit
   439      }
   440      "vsphere" {
   441        Create-Unattend -NewPassword $NewPassword -ProductKey $ProductKey `
   442          -Organization $Organization -Owner $Owner
   443  
   444        Invoke-Expression -Command 'C:/windows/system32/sysprep/sysprep.exe /generalize /oobe /unattend:"C:/Windows/Panther/Unattend/unattend.xml" /quiet /shutdown'
   445      }
   446      Default { Throw "Invalid IaaS '${IaaS}' supported platforms are: AWS, Azure, GCP and Vsphere" }
   447    }
   448  }
   449  
   450  function ModifyInfFile() {
   451    Param(
   452      [string]$InfFilePath = $(Throw "inf file path missing"),
   453      [string]$KeyName = $(Throw "keyname missing"),
   454      [string]$KeyValue = $(Throw "keyvalue missing")
   455    )
   456  
   457    $Regex = "^$KeyName"
   458    $TempFile = $InfFilePath + ".tmp"
   459  
   460    Get-Content $InfFilePath | ForEach-Object {
   461      $ValueToWrite=$_
   462      if($_ -match $Regex) {
   463        $ValueToWrite="$KeyName=$KeyValue"
   464      }
   465      $ValueToWrite | Out-File -Append $TempFile
   466    }
   467  
   468    Move-Item -Path $TempFile -Destination $InfFilePath -Force
   469  }
   470  
   471  function Allow-NTPSync() {
   472        Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config" -Name 'MaxNegPhaseCorrection' -Value 0xFFFFFFFF -Type dword
   473        Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\W32Time\Config" -Name 'MaxPosPhaseCorrection' -Value 0xFFFFFFFF -Type dword
   474  }