Last active
December 14, 2015 17:39
-
-
Save altrive/5124149 to your computer and use it in GitHub Desktop.
Windows Server 2012のWinSxSフォルダをインストールメディアから抽出、指定のディレクトリにコピーするPowerShellコマンドです。
インターネット未接続環境において、ディスク上から削除されている機能をインストールする際にこのWinSxsフォルダが必要となります
(例:ServerCoreへの機能追加等) WIMイメージのマウント(Mount-WindowsImage)は時間がかかるので、事前にWinSxSフォルダを抽出しネットワーク共有にコピーしておくと便利です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
.Synopsis | |
Extract WinSxS data from Windows Image and copy to destination folder | |
.Description | |
WinSxS is used to enable Windows features which removed from disk. | |
In offline environment. Enable feature in ServerCore installation need | |
WinSxS data that included in full installer image. | |
WIM extract takes long times operation | |
so, extract WinSxs and copy to network share and reuse it. | |
.Parameter MediaPath | |
ISO Media Image Path or Install Media Drive Root Path E:\ | |
.Parameter WimIndex | |
Specify Windows Image Index in WIM file. | |
if you need to enable features in ServerCore OS | |
you need to select correspod *Full* OS image Index. | |
* 1: Windows Server 2012 Standard Core | |
* 2: Windows Server 2012 Standard Full | |
* 3: Windows Server 2012 Datacenter Core | |
* 4: Windows Server 2012 Datacenter Full | |
.Parameter Destination | |
Target directory to copy WinSxs directory | |
.Example | |
$params=@{ | |
MediaPath = [ISO Media Path] | |
WimIndex = 4 #Windows Server 2012 Datacenter Image Index | |
Destination = [Copy Destination Path] | |
} | |
#Short Path | |
Copy-WindowsImageSxS @params | |
#> | |
function Copy-WindowsImageSxS | |
{ | |
param( | |
[Parameter(Mandatory=$true)] | |
[string]$MediaPath, | |
[Parameter(Mandatory=$true)] | |
[int]$WimIndex, | |
[Parameter(Mandatory=$true)] | |
[string]$Destination | |
) | |
Set-StrictMode -Version Latest | |
$ErrorActionPreference = "Stop" | |
#Create SxS distinaion Directory | |
if(!(Test-Path $Destination)) | |
{ | |
New-Item -Type Directory -Path $Destination | Out-Null | |
} | |
try{ | |
#Mount ISO Image or Resolve Media Drive | |
if([IO.Path]::GetExtension($MediaPath) -eq ".iso") | |
{ | |
Mount-DiskImage $MediaPath | |
$driveLetter = (Get-DiskImage $MediaPath | Get-Volume).DriveLetter | |
$wimPath= "{0}:\sources\install.wim" -f $driveLetter | |
} | |
else | |
{ | |
$wimPath= Join-Path $MediaPath "sources\install.wim" -Resolve | |
} | |
#Create Temp Directory to mount Windows Image | |
#if use GUID to directorynName, PathTooLongException occuer when call GetChildItem | |
$tempDir = [IO.Path]::GetTempFileName() | |
Remove-Item -Path $tempdir | |
New-Item -Type Directory -Path $tempdir | Out-Null #Create Directory(May Conflict Occured?) | |
#Mount Windows Image | |
Write-Verbose "Mounting Windows Image..." | |
Mount-WindowsImage -Path $tempDir -ImagePath $wimPath -Index $wimIndex -ReadOnly -Verbose:$False | Out-Null | |
#Copy WinSxS Directory | |
$fromDir = "$($tempDir)\Windows\WinSxS" | |
$totalSize = (Get-ChildItem $fromDir -Recurse | Measure-Object -Property Length -Sum).Sum | |
Write-Verbose ("WinSxs Folder Total Size: {0:N2} GB" -f ($totalSize / 1GB)) | |
Write-Verbose "Executing comand robocopy.exe $fromDir $Destination /S " | |
Write-Progress -Activity "Copying WinSxS Folder..." -Status "Start Copy" -PercentComplete 0 | |
$job = Start-Job {robocopy.exe $args[0] $args[1] /S | Out-Null} -ArgumentList $fromDir,$Destination | |
while ($job.State -ne "Completed" ) | |
{ | |
$items = (Get-ChildItem $Destination -Recurse | Measure-Object -Property Length -Sum) | |
if($items -ne $null) | |
{ | |
Write-Progress -Activity "Copying WinSxS Folder..." -Status "Copying Files" -PercentComplete (($items.Sum/$totalSize)*100) | |
} | |
sleep 5 | |
} | |
Write-Verbose "Copy Operation Finished" | |
Write-Progress -Activity "Copying WinSxS Folder..." -Completed | |
} | |
finally{ | |
#Cleanup | |
if([IO.Path]::GetExtension($MediaPath) -eq ".iso"){ | |
Dismount-DiskImage $MediaPath -ErrorAction SilentlyContinue | |
} | |
try{ | |
Dismount-WindowsImage -Path $tempDir -Discard -Verbose:$False| Out-Null | |
Remove-Item -Path $tempDir -ErrorAction SilentlyContinue | |
} | |
catch{ | |
$Host.UI.WriteErrorLine("Error occured in cleanup" + $_.Exception) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage Sampe:
this script download scripts from Gist. You need to check content is valid before using