[
  {
    "path": "DockerMsftProvider.psd1",
    "content": "#\n# Module manifest for module 'DockerMsftProvider'\n#\n# Generated by: jayshah\n#\n# Generated on: 08/12/2016\n#\n\n@{\n\n# Script module or binary module file associated with this manifest.\nRootModule = 'DockerMsftProvider.psm1'\n\n# Version number of this module.\nModuleVersion = '1.0.0.8'\n\n# ID used to uniquely identify this module\nGUID = '5beed3da-526b-47eb-9197-29c6a7214e4e'\n\n# Author of this module\nAuthor = 'jayshah'\n\n# Company or vendor of this module\nCompanyName = 'Microsoft'\n\n# Copyright statement for this module\nCopyright = '(c) 2016 Microsoft. All rights reserved.'\n\n# Description of the functionality provided by this module\nDescription = 'PowerShell module with commands for discovering, installing, and updating Docker images.'\n\n# Minimum version of the Windows PowerShell engine required by this module\nPowerShellVersion = '5.1'\n\n# Functions to export from this module\nFunctionsToExport = @()\n\n# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.\nPrivateData = @{\n    \"PackageManagementProviders\" = 'DockerMsftProvider.psm1'\n\n    PSData = @{\n        # Tags applied to this module. These help with module discovery in online galleries.\n        Tags = @('PackageManagement', 'Provider')\n        ProjectUri = 'https://github.com/OneGet/MicrosoftDockerProvider'\n        LicenseUri = 'https://github.com/OneGet/MicrosoftDockerProvider/blob/developer/LICENSE'\n        ReleaseNotes = @'\n- Docker Provider to find, save and install docker on windows.\n'@\n    } # End of PSData hashtable\n\n} # End of PrivateData hashtable\n}\n"
  },
  {
    "path": "DockerMsftProvider.psm1",
    "content": "\n#########################################################################################\n#\n# Copyright (c) Microsoft Corporation. All rights reserved.\n#\n# DockerMsftProvider\n#\n#########################################################################################\n\nMicrosoft.PowerShell.Core\\Set-StrictMode -Version Latest\n\n#region variables\n\n$script:Providername = \"DockerMsftProvider\"\n$script:DockerSources = $null\n$script:location_modules = Microsoft.PowerShell.Management\\Join-Path -Path $env:TEMP -ChildPath $script:ProviderName\n$script:location_sources= Microsoft.PowerShell.Management\\Join-Path -Path $env:LOCALAPPDATA -ChildPath $script:ProviderName\n$script:file_modules = Microsoft.PowerShell.Management\\Join-Path -Path $script:location_sources -ChildPath \"sources.txt\"\n$script:DockerSearchIndex = \"DockerSearchIndex.json\"\n$script:Installer_Extension = \"zip\"\n$script:dockerURL = \"https://go.microsoft.com/fwlink/?LinkID=825636&clcid=0x409\"\n$separator = \"|#|\"\n$script:restartRequired = $false\n$script:isNanoServerInitialized = $false\n$script:isNanoServer = $false\n$script:SystemEnvironmentKey = 'HKLM:\\System\\CurrentControlSet\\Control\\Session Manager\\Environment'\n$script:pathDockerRoot = Microsoft.PowerShell.Management\\Join-Path -Path $env:ProgramFiles -ChildPath \"Docker\"\n$script:pathDockerD = Microsoft.PowerShell.Management\\Join-Path -Path $script:pathDockerRoot -ChildPath \"dockerd.exe\"\n$script:pathDockerClient = Microsoft.PowerShell.Management\\Join-Path -Path $script:pathDockerRoot -ChildPath \"docker.exe\"\n$script:wildcardOptions = [System.Management.Automation.WildcardOptions]::CultureInvariant -bor `\n                          [System.Management.Automation.WildcardOptions]::IgnoreCase\n\n$script:NuGetProviderName = \"NuGet\"\n$script:NuGetBinaryProgramDataPath=\"$env:ProgramFiles\\PackageManagement\\ProviderAssemblies\"\n$script:NuGetBinaryLocalAppDataPath=\"$env:LOCALAPPDATA\\PackageManagement\\ProviderAssemblies\"\n$script:NuGetProvider = $null\n$script:nanoserverPackageProvider = \"NanoServerPackage\"\n$script:hotFixID = 'KB3176936'\n$script:minOsMajorBuild = 14393\n$script:minOSRevision= 206\n$script:MetadataFileName = 'metadata.json'\n$script:serviceName = \"docker\"\n$script:SemVerTypeName = 'Microsoft.PackageManagement.Provider.Utility.SemanticVersion'\nif('Microsoft.PackageManagement.NuGetProvider.SemanticVersion' -as [Type])\n{\n    $script:SemVerTypeName = 'Microsoft.PackageManagement.NuGetProvider.SemanticVersion'\n}\n\n#endregion variables\n\n#region One-Get Functions\n\nfunction Find-Package\n{\n    [CmdletBinding()]\n    param\n    (\n        [string[]]\n        $names,\n\n        [string]\n        $RequiredVersion,\n\n        [string]\n        $MinimumVersion,\n\n        [string]\n        $MaximumVersion\n    )\n\n    Set-ModuleSourcesVariable\n    $null = Install-NuGetClientBinary -CallerPSCmdlet $PSCmdlet\n\n    $options = $request.Options\n\n    foreach( $o in $options.Keys )\n    {\n        Write-Debug ( \"OPTION: {0} => {1}\" -f ($o, $options[$o]) )\n    }\n\n    $AllVersions = $null\n    if($options.ContainsKey(\"AllVersions\"))\n    {\n        $AllVersions = $options['AllVersions']\n    }\n\n    $sources = @()\n    if($options.ContainsKey('Source'))\n    {\n        $sources = $options['Source']\n    }\n\n    if ((-not $names) -or ($names.Count -eq 0))\n    {\n        $names = @('')\n    }\n\n    $allResults = @()\n    $allSources = Get-SourceList -Sources $sources\n\n    foreach($currSource in $allSources)\n    {\n        $Location = $currSource.SourceLocation\n        $sourceName = $currSource.Name\n\n        if($location.StartsWith(\"https://\"))\n        {\n            $tempResults = @()\n            $tempResults += Find-FromUrl -Source $Location `\n                                            -SourceName $sourceName `\n                                            -Name $names `\n                                            -MinimumVersion $MinimumVersion `\n                                            -MaximumVersion $MaximumVersion `\n                                            -RequiredVersion $RequiredVersion `\n                                            -AllVersions:$AllVersions\n\n            if($tempResults)\n            {\n                $allResults += $tempResults\n            }\n        }\n        else\n        {\n            Write-Error \"Currently only https sources are supported. Please register with https source.\"\n        }\n    }\n\n    if((-not $allResults) -or ($allResults.Count -eq 0))\n    {\n        return\n    }\n\n    foreach($result in $allResults)\n    {\n        $swid = New-SoftwareIdentityFromDockerInfo -DockerInfo $result\n        Write-Output $swid\n    }\n}\n\nfunction Download-Package\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [string]\n        $FastPackageReference,\n\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [string]\n        $Location\n    )\n\n    DownloadPackageHelper -FastPackageReference $FastPackageReference `\n                            -Request $Request `\n                            -Location $Location\n}\n\nfunction Install-Package\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [string]\n        $fastPackageReference\n    )\n\n    if(-not (Test-AdminPrivilege))\n    {\n        ThrowError -CallerPSCmdlet $PSCmdlet `\n                    -ExceptionName \"InvalidOperationException\" `\n                    -ExceptionMessage \"Administrator rights are required to install docker.\" `\n                    -ErrorId \"AdminPrivilegesAreRequiredForInstall\" `\n                    -ErrorCategory InvalidOperation\n    }\n\n    if(-not (IsNanoServer))\n    {\n        $osVersion = (Get-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\').CurrentBuildNumber\n        $osRevision = (Get-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\').UBR\n        # Ensure that the host is either running a build newer than Windows Server 2016 GA or\n        # if running Windows Server 2016 GA that it has a revision greater than 206 (KB3176936)\n        if (($osVersion -lt $script:minOsMajorBuild) -or \n        (($osVersion -eq $script:minOsMajorBuild) -and ($osRevision -lt $script:minOsRevision)))\n        {\n            ThrowError -CallerPSCmdlet $PSCmdlet `\n                        -ExceptionName \"InvalidOperationException\" `\n                        -ExceptionMessage \"$script:hotFixID or later is required for docker to work\" `\n                        -ErrorId \"RequiredWindowsUpdateNotInstalled\" `\n                        -ErrorCategory InvalidOperation\n            return\n        }\n\n        # This block should not be removed. It enforces Docker's support policy towards which\n        # SKU of Windows that Docker Engine - Enterprise is supported on. Windows 10 users should\n        # use Docker Desktop for Windows instead.\n        if ((Get-CimInstance Win32_Operatingsystem | Select-Object -expand Caption) -like \"*Windows 10*\")\n        {\n            ThrowError -CallerPSCmdlet $PSCmdlet `\n                        -ExceptionName \"InvalidOperationException\" `\n                        -ExceptionMessage \"Docker Engine - Enterprise is not supported on Windows 10 client. See https://aka.ms/docker-for-windows instead.\" `\n                        -ErrorId \"RequiresWindowsServer\" `\n                        -ErrorCategory InvalidOperation\n            return\n        }\n    }\n    else\n    {\n        Write-Warning \"$script:hotFixID or later is required for docker to work. Please ensure this is installed.\"\n    }\n\n    $options = $request.Options\n    $update = $false\n    $force = $false\n\n    if($options)\n    {\n        foreach( $o in $options.Keys )\n        {\n            Write-Debug (\"OPTION: {0} => {1}\" -f ($o, $request.Options[$o]) )\n        }\n\n        if($options.ContainsKey('Update'))\n        {\n            Write-Verbose \"Updating the docker installation.\"\n            $update = $true\n        }\n\n        if($options.ContainsKey(\"Force\"))\n        {\n            $force = $true\n        }\n    }\n\n    if(Test-Path $script:pathDockerD)\n    {\n        if($update -or $force)\n        {\n            # Uninstall if another installation exists\n            UninstallHelper\n        }\n        elseif(-not $force)\n        {\n            $dockerVersion = & \"$script:pathDockerClient\" --version\n            $resultArr = $dockerVersion -split \",\"\n            $version = ($resultArr[0].Trim() -split \" \")[2]\n\n            Write-Verbose \"Docker $version already exists. Skipping install. Use -force to install anyway.\"\n            return\n        }\n    }    \n    else\n    {\n        # Install WindowsFeature containers\n        try\n        {\n            InstallContainer\n        }\n        catch\n        {\n            $ErrorMessage = $_.Exception.Message\n            ThrowError -CallerPSCmdlet $PSCmdlet `\n                        -ExceptionName $_.Exception.GetType().FullName `\n                        -ExceptionMessage $ErrorMessage `\n                        -ErrorId FailedToDownload `\n                        -ErrorCategory InvalidOperation\n\n            return\n        }        \n    }\n\n    $splitterArray = @(\"$separator\")\n    $resultArray = $fastPackageReference.Split($splitterArray, [System.StringSplitOptions]::None)\n\n    if((-not $resultArray) -or ($resultArray.count -ne 8)){Write-Debug \"Fast package reference doesn't have required parts.\"}\n\n    $source = $resultArray[0]\n    $name = $resultArray[1]\n    $version = $resultArray[2]\n    $description = $resultArray[3]\n    $originPath = $resultArray[5]\n    $size = $resultArray[6]\n    $sha = $resultArray[7]\n    $date = $resultArray[4]\n    $Location = $script:location_modules\n\n    $destination = GenerateFullPath -Location $Location `\n                                    -Name $name `\n                                    -Version $Version\n\n    $downloadOutput = DownloadPackageHelper -FastPackageReference $FastPackageReference `\n                            -Request $Request `\n                            -Location $Location\n\n    if(-not (Test-Path $destination))\n    {\n        Write-Error \"$destination does not exist\"\n        return \n    }\n    else\n    {\n        Write-verbose \"Found $destination to install.\"\n    }\n\n    # Install\n    try \n    {\n        Write-Verbose \"Trying to unzip : $destination\"\n        $null = Expand-Archive -Path $destination -DestinationPath $env:ProgramFiles -Force\n\n        # Rename the docker folder to become Docker\n        $dummyName = 'dummyName'\n        $null = Rename-Item -Path $script:pathDockerRoot -NewName $env:ProgramFiles\\$dummyName\n        $null = Rename-Item -Path $env:ProgramFiles\\$dummyName -NewName $script:pathDockerRoot     \n\n        if(Test-Path $script:pathDockerD)\n        {\n            Write-Verbose \"Trying to enable the docker service...\"\n            $service = get-service -Name Docker -WarningAction SilentlyContinue -ErrorAction SilentlyContinue\n            if(-not $service)\n            {\n                & \"$script:pathDockerD\" --register-service\n            }\n        }\n        else\n        {\n            Write-Error \"Unable to expand docker to Program Files.\"\n        }\n    }\n    catch\n    {\n        $ErrorMessage = $_.Exception.Message\n        ThrowError -CallerPSCmdlet $PSCmdlet `\n                    -ExceptionName $_.Exception.GetType().FullName `\n                    -ExceptionMessage $ErrorMessage `\n                    -ErrorId FailedToDownload `\n                    -ErrorCategory InvalidOperation\n    }\n    finally\n    {\n        # Clean up\n        Write-Verbose \"Removing the archive: $destination\"\n        $null = remove-item $destination -Force\n    }\n\n    # Save the install information\n    $null = SaveInfo -Source $source\n\n    # Update the path variable\n    $null = Update-PathVar\n\n    if($script:restartRequired)\n    {\n        Write-Warning \"A restart is required to enable the containers feature. Please restart your machine.\"\n    }\n    \n    Write-Warning \"This provider is being deprecated and should no longer be used. Users should refer to the instructions on aka.ms/containers/install instead.\" \n\n    Write-Output $downloadOutput\n}\n\nfunction Uninstall-Package\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [string]\n        $fastPackageReference\n    )\n\n    UninstallHelper\n\n    Write-Verbose \"Uninstalling container feature from windows\"\n    UninstallContainer\n\n    [string[]] $splitterArray = @(\"$separator\")\n    [string[]] $resultArray = $fastPackageReference.Split($splitterArray, [System.StringSplitOptions]::None)\n\n    if((-not $resultArray) -or ($resultArray.count -ne 3)){Write-Debug \"Fast package reference doesn't have required parts.\"}\n\n    $name = $resultArray[0]\n    $version = $resultArray[1]\n    $source = $resultArray[2]\n\n    $dockerSWID = @{\n            Name = $name\n            version = $version\n            Source = $source\n            versionScheme = \"MultiPartNumeric\"\n            fastPackageReference = $fastPackageReference\n    }\n\n    New-SoftwareIdentity @dockerSWID\n}\n\n#endregion One-Get Functions\n\n#region One-Get Required Functions\n\nfunction Initialize-Provider\n{\n    write-debug \"In $($script:Providername) - Initialize-Provider\"\n}\n\nfunction Get-PackageProviderName\n{\n    return $script:Providername\n}\n\nfunction Get-InstalledPackage\n{\n    param\n    (\n        [string]$name,\n        [string]$requiredVersion,\n        [string]$minimumVersion,\n        [string]$maximumVersion\n    )\n\n    $name = 'docker'\n    $version = ''\n    $source = ''\n\n    if(Test-Path $script:pathDockerRoot\\$script:MetadataFileName) \n    {\n        $metaContent = (Get-Content -Path $script:pathDockerRoot\\$script:MetadataFileName)\n\n        if(IsNanoServer)\n        {\n            $jsonDll = [Microsoft.PowerShell.CoreCLR.AssemblyExtensions]::LoadFrom($PSScriptRoot + \"\\Json.coreclr.dll\")\n            $jsonParser = $jsonDll.GetTypes() | Where-Object name -match jsonparser\n            $metaContentParsed = $jsonParser::FromJson($metaContent)\n\n            $source = if($metaContentParsed.ContainsKey('SourceName')) {$metaContentParsed.SourceName} else {'Unable To Retrieve Source from metadata.json'}\n            $version = if($metaContentParsed.ContainsKey('Version')) {$metaContentParsed.Version} else {'Unable To Retrieve Version from metadata.json'}\n        }\n        else\n        {\n            $metaContentParsed = (Get-Content -Path $script:pathDockerRoot\\$script:MetadataFileName) | ConvertFrom-Json\n            if($metaContentParsed)\n            {\n                $source = if($metaContentParsed.PSObject.properties.name -contains 'SourceName') {$metaContentParsed.SourceName} else {'Unable To Retrieve Source from metadata.json'}\n                $version = if($metaContentParsed.PSObject.properties.name -contains 'Version') {$metaContentParsed.Version} else {'Unable To Retrieve Version from metadata.json'}\n            }            \n        }\n    }\n    elseif(Test-Path $script:pathDockerD)\n    {\n        $dockerVersion = & \"$script:pathDockerClient\" --version\n        $resultArr = $dockerVersion -split \",\"\n        $version = ($resultArr[0].Trim() -split \" \")[2]\n        $source = ' '\n    }\n    else\n    {\n        return $null\n    }\n\n    $fastPackageReference = $name +\n                                    $separator + $version +\n                                    $separator + $source\n\n    $dockerSWID = @{\n        Name = $name\n        version = $version\n        Source = $source\n        versionScheme = \"MultiPartNumeric\"\n        fastPackageReference = $fastPackageReference\n    }\n\n    return New-SoftwareIdentity @dockerSWID\n}\n\n#endregion One-Get Required Functions\n\n#region Helper-Functions\n\nfunction SaveInfo\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $Source\n    )\n\n    # Create a file\n    $metaFileInfo = New-Item -ItemType File -Path $script:pathDockerRoot -Name $script:MetadataFileName -Force\n\n    if(-not $metaFileInfo)\n    {\n        # TODO: Handle File not created scenario\n    }\n\n    if(Test-Path $script:pathDockerD)\n    {\n        $dockerVersion = & \"$script:pathDockerD\" --version\n        $resultArr = $dockerVersion -split \",\"\n        $version = ($resultArr[0].Trim() -split \" \")[2]\n\n        $metaInfo = Microsoft.PowerShell.Utility\\New-Object PSCustomObject -Property ([ordered]@{\n            SourceName = $source\n            Version = $version \n        })\n\n        $metaInfo | ConvertTo-Json > $metaFileInfo\n    }\n}\n\nfunction UninstallHelper\n{\n    if(-not (Test-AdminPrivilege))\n    {\n        ThrowError -CallerPSCmdlet $PSCmdlet `\n                    -ExceptionName \"InvalidOperationException\" `\n                    -ExceptionMessage \"Administrator rights are required to install docker.\" `\n                    -ErrorId \"AdminPrivilegesAreRequiredForInstall\" `\n                    -ErrorCategory InvalidOperation\n    }\n\n    # Stop docker service\n    $dockerService = get-service -Name Docker -WarningAction SilentlyContinue -ErrorAction SilentlyContinue\n    if(-not $dockerService)\n    {\n        # Docker service is not available\n        Write-Warning \"Docker Service is not available.\"\n    }\n\n    if(($dockerService.Status -eq \"Started\") -or ($dockerService.Status -eq \"Running\"))\n    {\n        Write-Verbose \"Trying to stop docker service\"\n        $null = stop-service docker\n    }\n\n    if(Test-Path $script:pathDockerD)\n    {\n        Write-Verbose \"Unregistering the docker service\"\n        $null = & \"$script:pathDockerD\" --unregister-service\n        \n        Write-Verbose \"Removing the docker files\"\n        $null = Get-ChildItem -Path $script:pathDockerRoot -Recurse | Remove-Item -force -Recurse\n\n        if(Test-Path $script:pathDockerRoot ) {$null = Remove-Item $script:pathDockerRoot  -Force}\n    }\n    else \n    {\n        Write-Warning \"Docker is not present under the Program Files. Please check the installation.\"\n    }\n\n    Write-Verbose \"Removing the path variable\"\n    $null = Remove-PathVar\n}\n\nfunction InstallContainer\n{\n    if(IsNanoServer)\n    {        \n        if(HandleProvider)\n        {\n            $containerExists = get-package -providername NanoServerPackage -Name *container* -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n\n            if($containerExists)\n            {\n                Write-Verbose \"Containers package is already installed. Skipping the install.\"\n                return\n            }\n\n            # Find Container Package\n            $containerPackage = Find-NanoServerPackage -Name *Container* -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n\n            if(-not $containerPackage)\n            {\n                ThrowError -ExceptionName \"System.ArgumentException\" `\n                            -ExceptionMessage \"Unable to find the Containers Package from NanoServerPackage Module.\" `\n                            -ErrorId \"PackageNotFound\" `\n                            -CallerPSCmdlet $PSCmdlet `\n                            -ErrorCategory InvalidOperation\n            }\n\n            Write-Verbose \"Installing Containers...\"\n            $null = $containerPackage | Install-NanoServerPackage -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n            $script:restartRequired = $true\n        }\n        else\n        {\n            ThrowError -ExceptionName \"System.ArgumentException\" `\n                            -ExceptionMessage \"Unable to load the NanoServerPackage Module.\" `\n                            -ErrorId \"ModuleNotFound\" `\n                            -CallerPSCmdlet $PSCmdlet `\n                            -ErrorCategory InvalidOperation\n        }\n    }\n    else\n    {\n        $containerExists = Get-WindowsFeature -Name Containers\n        \n        if($containerExists -and $containerExists.Installed)\n        {\n            Write-Verbose \"Containers feature is already installed. Skipping the install.\"\n            return\n        }\n        else\n        {\n            Write-Verbose \"Installing Containers feature...\"\n            Install-WindowsFeature containers\n            $script:restartRequired = $true            \n        }\n    }\n\n    Write-Verbose \"Installed Containers feature\"\n}\n\nfunction UninstallContainer\n{\n    if(IsNanoServer)\n    {\n        return\n    }\n    else\n    {\n        Uninstall-WindowsFeature containers\n    }\n}\n\nfunction HandleProvider\n{\n    # Get the nanoServerpackage provider is present\n    $getnanoServerPackage = Get-PackageProvider -Name $script:nanoserverPackageProvider -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n\n    # if not download and install\n    if(-not $getnanoServerPackage)\n    {\n        $repositories = Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n        if(-not $repositories){$null = Register-PSRepository -Default}\n\n        $nanoserverPackage = Find-Module -Name $script:nanoserverPackageProvider -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Repository PSGallery\n        if(-not $nanoserverPackage)\n        {\n            ThrowError -ExceptionName \"System.ArgumentException\" `\n                        -ExceptionMessage \"Unable to find the Containers Package from NanoServerPackage Module.\" `\n                        -ErrorId \"PackageNotFound\" `\n                        -CallerPSCmdlet $PSCmdlet `\n                        -ErrorCategory InvalidOperation\n        }\n\n        # Install the provider \n        $null = $nanoserverPackage | Install-Module -Force -SkipPublisherCheck\n    }\n    \n    # Import the provider\n    $importProvider = Import-PackageProvider -Name $script:nanoserverPackageProvider -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue\n    $importModule = Import-module -Name $script:nanoserverPackageProvider -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -PassThru\n\n    return ($importModule -and $importProvider)\n}\n\nfunction Update-PathVar\n{\n    $NameOfPath = \"Path\"\n    \n    # Set the environment variable in the Local Process\n    $envVars = [Environment]::GetEnvironmentVariable($NameOfPath)\n    $envArr = @()\n    $envArr = $envVars -split ';'\n    $envFlag = $true\n    foreach($envItem in $envArr) \n    {\n        if($envItem.Trim() -match [regex]::Escape($script:pathDockerRoot)) \n        {\n            $envFlag = $false\n            break\n        }\n    }\n    if($envFlag)\n    {\n        $null = [Environment]::SetEnvironmentVariable($NameOfPath, $envVars + \";\" + $script:pathDockerRoot)\n    }\n\n    # Set the environment variable in the Machine\n    $currPath = (Microsoft.PowerShell.Management\\Get-ItemProperty -Path $script:SystemEnvironmentKey -Name $NameOfPath -ErrorAction SilentlyContinue).Path    \n    $currArr = @()\n    $currArr = $currPath -split ';'\n    $currFlag = $true\n    foreach($currItem in $currArr)\n    {\n        if($currItem.Trim() -match [regex]::Escape($script:pathDockerRoot)) \n        {\n            $currFlag = $false\n            break\n        }\n    }\n    if($currFlag)\n    {\n        $null = Microsoft.PowerShell.Management\\Set-ItemProperty $script:SystemEnvironmentKey -Name $NameOfPath -Value ($currPath + \";\" + $script:pathDockerRoot)\n\n        # Nanoserver needs a reboot to persist the registry change\n        if(IsNanoServer)\n        {\n            $script:restartRequired = $true\n        }        \n    }\n}\n\nfunction Remove-PathVar\n{\n    $NameOfPath = \"Path\"\n\n    # Set the environment variable in the Local Process\n    $envVars = [Environment]::GetEnvironmentVariable($NameOfPath)\n    $envArr = @()\n    $envArr = $envVars -split ';'\n    $envFlag = $false\n    foreach($envItem in $envArr) \n    {\n        if($envItem.Trim() -match [regex]::Escape($script:pathDockerRoot))\n        {\n            $envFlag = $true\n            break\n        }\n    }\n    if($envFlag)\n    {\n        $newPath = $envVars -replace [regex]::Escape($script:pathDockerRoot),$null\n        $newPath = $newPath -replace (\";;\"), \";\"\n        $null = [Environment]::SetEnvironmentVariable($NameOfPath, $newPath)\n    }\n\n    # Set the environment variable in the Machine\n    $currPath = (Microsoft.PowerShell.Management\\Get-ItemProperty -Path $script:SystemEnvironmentKey -Name $NameOfPath -ErrorAction SilentlyContinue).Path\n    $currArr = @()\n    $currArr = $currPath -split ';'\n    $currFlag = $false\n    foreach($currItem in $currArr)\n    {\n        if($currItem.Trim() -match [regex]::Escape($script:pathDockerRoot))\n        {\n            $currFlag = $true\n            break\n        }\n    }\n    if($currFlag)\n    {\n        $newPath = $currPath -replace [regex]::Escape($script:pathDockerRoot),$null\n        $newPath = $newPath -replace (\";;\"), \";\"\n        $null = Microsoft.PowerShell.Management\\Set-ItemProperty $script:SystemEnvironmentKey -Name $NameOfPath -Value $newPath\n    }\n}\n\nfunction Set-ModuleSourcesVariable\n{\n    if(Microsoft.PowerShell.Management\\Test-Path $script:file_modules)\n    {\n        $script:DockerSources = DeSerialize-PSObject -Path $script:file_modules\n    }\n    else\n    {\n        $script:DockerSources = [ordered]@{}\n        $defaultModuleSource = Microsoft.PowerShell.Utility\\New-Object PSCustomObject -Property ([ordered]@{\n            Name = \"DockerDefault\"\n            SourceLocation = $script:dockerURL\n            Trusted=$false\n            Registered= $true\n            InstallationPolicy = \"Untrusted\"\n        })\n\n        $script:DockerSources.Add(\"DockerDefault\", $defaultModuleSource)\n        Save-ModuleSources\n    }\n}\n\nfunction DeSerialize-PSObject\n{\n    [CmdletBinding(PositionalBinding=$false)]\n    Param\n    (\n        [Parameter(Mandatory=$true)]        \n        $Path\n    )\n    $filecontent = Microsoft.PowerShell.Management\\Get-Content -Path $Path\n    [System.Management.Automation.PSSerializer]::Deserialize($filecontent)    \n}\n\nfunction Save-ModuleSources\n{\n    # check if exists\n    if(-not (Test-Path $script:location_sources))\n    {\n        $null = mkdir $script:location_sources\n    }\n\n    # seralize module\n    Microsoft.PowerShell.Utility\\Out-File -FilePath $script:file_modules `\n                                            -Force `\n                                            -InputObject ([System.Management.Automation.PSSerializer]::Serialize($script:DockerSources))\n}\n\nfunction Get-SourceList\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]        \n        $sources\n    )\n\n    Set-ModuleSourcesVariable\n\n    $listOfSources = @()    \n    \n    foreach($mySource in $script:DockerSources.Values)\n    {\n        if((-not $sources) -or\n            (($mySource.Name -eq $sources) -or\n               ($mySource.SourceLocation -eq $sources)))\n        {\n            $tempHolder = @{}\n\n            $location = $mySource.\"SourceLocation\"\n            $tempHolder.Add(\"SourceLocation\", $location)\n            \n            $packageSourceName = $mySource.Name\n            $tempHolder.Add(\"Name\", $packageSourceName)\n            \n            $listOfSources += $tempHolder\n        }\n    }\n\n    return $listOfSources\n}\n\nfunction Resolve-ChannelAlias\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [psobject]\n        $Channels,\n\n        [Parameter(Mandatory=$true)]\n        [String]\n        $Channel\n    )\n\n    while ($Channels.$Channel.PSObject.Properties.Name -contains 'alias')\n    {\n        $Channel = $Channels.$Channel.alias\n    }\n\n    return $Channel\n}\n\nfunction Find-FromUrl\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [Uri]\n        $Source,\n\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $SourceName,\n\n        [Parameter(Mandatory=$false)]\n        [string[]]\n        $Name,\n\n        [Parameter(Mandatory=$false)]\n        [String]\n        $MinimumVersion,\n\n        [Parameter(Mandatory=$false)]\n        [String]\n        $MaximumVersion,\n        \n        [Parameter(Mandatory=$false)]\n        [String]\n        $RequiredVersion,\n\n        [Parameter(Mandatory=$false)]\n        [switch]\n        $AllVersions\n    )\n\n    if ([string]::IsNullOrWhiteSpace($Name))\n    {\n        $Name = \"*\"\n    }\n\n    if ([System.Management.Automation.WildcardPattern]::ContainsWildcardCharacters($Name))\n    {\n        if('docker' -notlike $Name) {return $null}\n    }\n    elseif('docker' -ne $Name) {return $Null}\n\n    $searchFile = Get-SearchIndex -fwdLink $Location `\n                                    -SourceName $SourceName\n\n    [String] $searchFileContent = Get-Content -Path $searchFile\n\n    if(-not $searchFileContent)\n    {\n        return $null\n    }   \n\n    $updatedContent = $searchFileContent.Trim(\" .-`t`n`r\")    \n    $contents = $updatedContent | ConvertFrom-Json\n    $channels = $contents.channels\n    $versions = $contents.versions\n    $channelValues = $channels | Get-Member -MemberType NoteProperty\n    $searchResults = @()\n\n    # If name is null or whitespace, interpret as *\n    if ([string]::IsNullOrWhiteSpace($Name))\n    {\n        $Name = \"*\"\n    }\n\n    # Set the default channel, allowing $RequiredVersion to override when set to a channel name.\n    $defaultChannel = 'cs'\n    if ($RequiredVersion)\n    {\n        foreach ($channel in $channelValues)\n        {\n            if ($RequiredVersion -eq $channel.Name)\n            {\n                $defaultChannel = $channel.Name\n                $RequiredVersion = $null\n                break\n            }\n        }\n    }\n\n    # if no versions are mentioned, just provide the default version, i.e.: CS \n    if((-not ($MinimumVersion -or $MaximumVersion -or $RequiredVersion -or $AllVersions)))\n    {\n        $resolvedChannel = Resolve-ChannelAlias -Channels $channels -Channel $defaultChannel\n        $RequiredVersion = $channels.$resolvedChannel.version\n    }\n\n    # if a particular version is requested, provide that version only\n    if($RequiredVersion)\n    {\n        if($versions.PSObject.properties.name -contains $RequiredVersion)\n        {\n            $obj = Get-ResultObject -JSON $versions -Version $RequiredVersion\n            $searchResults += $obj\n            return $searchResults\n        }\n        else {\n            return $null\n        }\n    }\n\n    $savedVersion = New-Object $script:SemVerTypeName -ArgumentList '0.0.0'\n    \n    # version requirement\n    # compare different versions\n    foreach($channel in $channelValues)\n    {\n        if ($channel.Name -eq $defaultChannel)\n        {\n            continue\n        }\n        else \n        {\n            $dockerName = \"Docker\"\n            $versionName = Resolve-ChannelAlias -Channels $channels -Channel $channel.Name\n            $versionValue = $channels.$versionName.version\n\n            $toggle = $false\n\n            # Check if the search string has * in it\n            if ([System.Management.Automation.WildcardPattern]::ContainsWildcardCharacters($Name))\n            {\n                if($dockerName -like $Name)\n                {\n                    $toggle = $true\n                }\n                else\n                {\n                    continue\n                }\n            }\n            else\n            {\n                if($dockerName -eq $Name)\n                {\n                    $toggle = $true\n                }\n                else\n                {\n                    continue\n                }\n            }\n\n            $thisVersion = New-Object $script:SemVerTypeName -ArgumentList $versionValue\n\n            if($MinimumVersion)\n            {\n                $convertedMinimumVersion =  New-Object $script:SemVerTypeName -ArgumentList $MinimumVersion\n                if($thisVersion -ge $convertedMinimumVersion)\n                {\n                    $toggle = $true\n                }\n                else \n                {\n                    $toggle = $false\n                    continue\n                }\n            }\n\n            if($MaximumVersion)\n            {\n                $convertedMaximumVersion =  New-Object $script:SemVerTypeName -ArgumentList $MaximumVersion\n                if($thisVersion -le $convertedMaximumVersion)\n                {\n                    $toggle = $true\n                }\n                else\n                {\n                    $toggle = $false\n                    continue\n                }\n            }\n\n            if($toggle)\n            {\n                if($thisVersion -ge $savedVersion) {$savedVersion = $thisVersion}\n            }\n\n            if($AllVersions)\n            {\n                if($toggle)\n                {\n                    $obj = Get-ResultObject -JSON $versions -Version $versionValue\n                    $searchResults += $obj\n                }\n            }\n        }\n    }\n\n    if(-not $AllVersions)\n    {\n        if($savedVersion -eq '0.0.0'){return $null}\n\n        $ver = $savedVersion.ToString()\n        $obj = Get-ResultObject -JSON $versions -Version $ver\n        $searchResults += $obj\n    }\n\n    return $searchResults\n}\n\nfunction Get-ResultObject\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [string]\n        $Version,\n\n        [Parameter(Mandatory=$true)]\n        [psobject]\n        $JSON\n    )\n\n    if($JSON.$Version)\n    {   \n        $description = \"\"\n        if($versions.$Version.Psobject.properties.name -contains \"notes\")\n        {\n            $URL = $versions.$Version.'notes'\n            if($URL.StartsWith(\"https://\"))\n            {\n                try\n                {\n                    $description = (Invoke-WebRequest -Uri $URL).Content\n                }\n                catch\n                {\n                    Write-verbose \"Bad URL provided for description: $URL\"\n                }\n            }\n            else\n            {\n                $description = $versions.$Version.'notes'\n            }\n        }\n\n        $obj = $versions.$Version.PSObject.Copy()\n        $null = $obj | Add-Member NoteProperty Version $Version\n        $null = $obj | Add-Member NoteProperty Name \"Docker\"\n        $null = $obj | Add-Member NoteProperty SourceName $SourceName\n        $null = $obj | Add-Member NoteProperty Description $description\n\n        return $obj\n    }\n    \n    return $null\n}\n\nfunction Get-SearchIndex\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [string]\n        $fwdLink,\n\n        [Parameter(Mandatory=$true)]\n        [string]\n        $SourceName\n    )\n\n    $fullUrl = Resolve-FwdLink $fwdLink\n    $searchIndex = $SourceName + \"_\" + $script:DockerSearchIndex\n    $destination = Join-Path $script:location_modules $searchIndex\n\n    if(-not(Test-Path $script:location_modules))\n    {\n        $null = mkdir $script:location_modules\n    }\n\n    if(Test-Path $destination)\n    {\n        $null = Remove-Item $destination\n        $null = DownloadFile -downloadURL $fullUrl `\n                    -destination $destination\n    }\n    else\n    {\n        $null = DownloadFile -downloadURL $fullUrl `\n                    -destination $destination\n    }\n    \n    return $destination\n}\n\nfunction Resolve-FwdLink\n{\n    param\n    (\n        [parameter(Mandatory=$false)]\n        [System.String]$Uri\n    )\n    \n    $response = Get-HttpResponse -Uri $Uri\n\n    if(-not $response)\n    {\n        # This is not a forward link. Return the original URI\n        return $Uri\n    }\n\n    $link = $response.Result.RequestMessage.RequestUri\n    $fullUrl = $link.AbsoluteUri\n    return $fullUrl\n}\n\nfunction Get-HttpResponse\n{\n    param\n    (\n        [Parameter(Mandatory=$false)]\n        [System.String]\n        $Uri\n    )\n\n    if(-not (IsNanoServer))\n    {\n        Add-Type -AssemblyName System.Net.Http\n    }\n\n    $httpClient = New-Object System.Net.Http.HttpClient\n    $request = New-Object System.Net.Http.HttpRequestMessage\n    $request.Method = [System.Net.Http.HttpMethod]::Head\n    $request.RequestUri = $Uri\n    $response = $httpclient.SendAsync($request)\n\n    return $response\n}\n\nfunction New-SoftwareIdentityFromDockerInfo\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [PSCustomObject]\n        $DockerInfo\n    )\n\n    $fastPackageReference = $DockerInfo.SourceName +\n                                $separator + $DockerInfo.Name + \n                                $separator + $DockerInfo.Version + \n                                $separator + $DockerInfo.Description  +\n                                $separator + $dockerInfo.date +\n                                $separator + $dockerInfo.url  +\n                                $separator + $dockerInfo.size +\n                                $separator + $dockerInfo.sha256\n    \n    $params = @{\n                    FastPackageReference = $fastPackageReference;\n                    Name = $DockerInfo.Name;\n                    Version = $DockerInfo.Version;\n                    Source = $DockerInfo.SourceName;\n                    versionScheme  = \"MultiPartNumeric\";\n                    Summary = $DockerInfo.Description;                    \n                }\n\n    New-SoftwareIdentity @params\n}\n\nfunction Set-ModuleSourcesVariable\n{\n    [CmdletBinding()]\n    param([switch]$Force)\n\n    if(Microsoft.PowerShell.Management\\Test-Path $script:file_modules)\n    {\n        $script:DockerSources = DeSerialize-PSObject -Path $script:file_modules\n    }\n    else\n    {\n        $script:DockerSources = [ordered]@{}\n                \n        $defaultModuleSource = Microsoft.PowerShell.Utility\\New-Object PSCustomObject -Property ([ordered]@{\n            Name = \"DockerDefault\"\n            SourceLocation = $script:dockerURL\n            Trusted=$false\n            Registered= $true\n            InstallationPolicy = \"Untrusted\"\n        })\n\n        $script:DockerSources.Add(\"DockerDefault\", $defaultModuleSource)\n        Save-ModuleSources\n    }\n}\n\nfunction Get-DynamicOptions\n{\n    param\n    (\n        [Microsoft.PackageManagement.MetaProvider.PowerShell.OptionCategory]\n        $category\n    )\n\n    switch($category)\n    {\n        Install \n        {\n            Write-Output -InputObject (New-DynamicOption -Category $category -Name \"Update\" -ExpectedType Switch -IsRequired $false)\n        }\n    }\n}\n\nfunction Add-PackageSource\n{\n    [CmdletBinding()]\n    param\n    (\n        [string]\n        $Name,\n         \n        [string]\n        $Location,\n\n        [bool]\n        $Trusted\n    )\n\n    Set-ModuleSourcesVariable\n\n    $Options = $request.Options\n\n    # Add new module source\n    $moduleSource = Microsoft.PowerShell.Utility\\New-Object PSCustomObject -Property ([ordered]@{\n            Name = $Name\n            SourceLocation = $Location            \n            Trusted=$Trusted\n            Registered= $true\n            InstallationPolicy = if($Trusted) {'Trusted'} else {'Untrusted'}\n    })\n\n    #TODO: Check if name already exists\n    $script:DockerSources.Add($Name, $moduleSource)\n\n    Save-ModuleSources\n\n    Write-Output -InputObject (New-PackageSourceFromModuleSource -ModuleSource $moduleSource)\n}\n\nfunction Remove-PackageSource\n{\n    param\n    (\n        [string]\n        $Name\n    )\n    \n    Set-ModuleSourcesVariable -Force\n\n    if(-not $script:DockerSources.Contains($Name))\n    {\n        Write-Error -Message \"Package source $Name not found\" `\n                        -ErrorId \"Package source $Name not found\" `\n                        -Category InvalidOperation `\n                        -TargetObject $Name\n        continue\n    }\n\n    $script:DockerSources.Remove($Name)\n\n    Save-ModuleSources\n}\n\nfunction Resolve-PackageSource\n{\n    Set-ModuleSourcesVariable\n    $SourceName = $request.PackageSources\n    if(-not $SourceName)\n    {\n        $SourceName = \"*\"\n    }\n\n    foreach($moduleSourceName in $SourceName)\n    {\n        if($request.IsCanceled)\n        {\n            return\n        }\n\n        $wildcardPattern = New-Object System.Management.Automation.WildcardPattern $moduleSourceName,$script:wildcardOptions\n        $moduleSourceFound = $false\n\n        $script:DockerSources.GetEnumerator() |  \n            Microsoft.PowerShell.Core\\Where-Object {$wildcardPattern.IsMatch($_.Key)} |  \n                Microsoft.PowerShell.Core\\ForEach-Object { \n                    $moduleSource = $script:DockerSources[$_.Key] \n                    $packageSource = New-PackageSourceFromModuleSource -ModuleSource $moduleSource \n                    Write-Output -InputObject $packageSource \n                    $moduleSourceFound = $true \n                }\n\n        if(-not $moduleSourceFound)\n        {\n            $sourceName  = Get-SourceName -Location $moduleSourceName\n\n            if($sourceName)\n            {\n                $moduleSource = $script:DockerSources[$sourceName]\n                $packageSource = New-PackageSourceFromModuleSource -ModuleSource $moduleSource\n                Write-Output -InputObject $packageSource\n            }            \n        }\n    }\n}\n\nfunction New-PackageSourceFromModuleSource\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        $ModuleSource\n    )\n\n    $packageSourceDetails = @{}\n\n    # create a new package source\n    $src =  New-PackageSource -Name $ModuleSource.Name `\n                              -Location $ModuleSource.SourceLocation `\n                              -Trusted $ModuleSource.Trusted `\n                              -Registered $ModuleSource.Registered `\n                              -Details $packageSourceDetails\n\n    # return the package source object.\n    Write-Output -InputObject $src\n}\n\nfunction Get-SourceName\n{\n    [CmdletBinding()]\n    [OutputType(\"string\")]\n    Param\n    (\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [string]\n        $Location\n    )\n\n    Set-ModuleSourcesVariable\n\n    foreach($psModuleSource in $script:DockerSources.Values)\n    {\n        if(($psModuleSource.Name -eq $Location) -or\n           ($psModuleSource.SourceLocation -eq $Location))\n        {\n            return $psModuleSource.Name\n        }\n    }\n}\n\nfunction DownloadPackageHelper\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [string]\n        $FastPackageReference,\n\n        [Parameter()]\n        [ValidateNotNullOrEmpty()]\n        [string]\n        $Location,\n\n        [Parameter(Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        $request\n    )\n\n    [string[]] $splitterArray = @(\"$separator\")\n    [string[]] $resultArray = $fastPackageReference.Split($splitterArray, [System.StringSplitOptions]::None)\n\n    if((-not $resultArray) -or ($resultArray.count -ne 8)){Write-Debug \"Fast package reference doesn't have required parts.\"}\n\n    $source = $resultArray[0]\n    $name = $resultArray[1]\n    $version = $resultArray[2]\n    $description = $resultArray[3]\n    $originPath = $resultArray[5]\n    $size = $resultArray[6]\n    $sha = $resultArray[7]\n    $date = $resultArray[4]\n\n    $options = $request.Options\n\n    foreach( $o in $options.Keys )\n    {\n        Write-Debug ( \"OPTION: {0} => {1}\" -f ($o, $options[$o]) )\n    }\n\n    $Force = $false\n    if($options.ContainsKey(\"Force\"))\n    {\n        $Force = $options['Force']\n    }\n\n    if(-not (Test-Path $Location))\n    {\n        if($Force)\n        {\n            Write-Verbose \"Creating: $Location as it doesn't exist.\"\n            mkdir $Location\n        }\n        else\n        {\n            $errorMessage = (\"Cannot find the path '{0}' because it does not exist\" -f $Location)\n            ThrowError  -ExceptionName \"System.ArgumentException\" `\n                    -ExceptionMessage $errorMessage `\n                    -ErrorId \"PathNotFound\" `\n                    -CallerPSCmdlet $PSCmdlet `\n                    -ExceptionObject $Location `\n                    -ErrorCategory InvalidArgument\n        }\n    }\n\n    $fullDestinationPath = GenerateFullPath -Location $Location `\n                                    -Name $name `\n                                    -Version $Version\n\n    if(Test-Path $fullDestinationPath)\n    {\n        if($Force)\n        {\n            $existingFileItem = get-item $fullDestinationPath\n            if($existingFileItem.isreadonly)\n            {\n                throw \"Cannot remove read-only file $fullDestinationPath. Remove read-only and use -Force again.\"\n            }\n            else\n            {\n                Write-Verbose \"$fullDestinationPath already exists. Deleting and downloading again.\"\n                Remove-Item $fullDestinationPath -Force\n                DownloadFile -downloadUrl $originPath -destination $fullDestinationPath\n            }\n        }\n        else\n        {\n            Write-Verbose \"$fullDestinationPath already exists. Skipping save. Use -Force to overwrite.\"\n        }\n    }\n    else\n    {\n        DownloadFile -downloadUrl $originPath -destination $fullDestinationPath\n    }\n\n    $hashCheck = VerifyHashCheck -destination $fullDestinationPath -hash $sha\n\n    if((-not $hashCheck))\n    {\n        $null = remove-item -Path $fullDestinationPath -Force\n        Write-Error -Message \"Cannot verify the file SHA256. Deleting the file.\"                \n    }\n\n    Write-Verbose \"Hash verified!\"\n\n    $savedWindowsPackageItem = Microsoft.PowerShell.Utility\\New-Object PSCustomObject -Property ([ordered]@{\n                        SourceName = $source\n                        Name = $name\n                        Version = $version\n                        Description = $description \n                        Date = $date\n                        URL = $originPath\n                        Size = $size\n                        sha256 = $sha\n    })\n\n    Write-Output (New-SoftwareIdentityFromDockerInfo $savedWindowsPackageItem)\n}\n\nfunction GenerateFullPath\n{\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [System.String]\n        $Location,\n\n        [Parameter(Mandatory=$true)]\n        [System.String]\n        $Name,\n\n        [Parameter(Mandatory=$true)]\n        [System.String]\n        $Version\n    )\n\n    $fileExtension = \".\" + $script:Installer_Extension\n    $Name = $Name.TrimEnd($fileExtension)\n    $fileName = $Name + \"-\" + $Version.ToString().replace('.','-') + $fileExtension\n    $fullPath = Join-Path $Location $fileName\n    return $fullPath\n}\n\nfunction DownloadFile\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory=$true)]\n        [System.String]\n        $downloadURL, \n        \n        [Parameter(Mandatory=$true)]\n        [System.String]\n        $destination\n    )\n\n    try\n    {\n        if(-not (CheckDiskSpace -Destination $destination -URL $downloadURL))\n        {\n            return\n        }\n\n        # Download the file\n        if($downloadURL.StartsWith(\"https://\"))\n        {\n            Write-Verbose \"Downloading $downloadUrl to $destination\"\n            $startTime = Get-Date\n            Write-Verbose \"About to download\"\n            Invoke-WebRequest -Uri $downloadURL `\n                            -OutFile $destination\n\n            Write-Verbose \"Finished downloading\"\n            $endTime = Get-Date\n            $difference = New-TimeSpan -Start $startTime -End $endTime\n            $downloadTime = \"Downloaded in \" + $difference.Hours + \" hours, \" + $difference.Minutes + \" minutes, \" + $difference.Seconds + \" seconds.\"\n            Write-Verbose $downloadTime\n        }\n    }\n    catch\n    {\n        ThrowError -CallerPSCmdlet $PSCmdlet `\n                    -ExceptionName $_.Exception.GetType().FullName `\n                    -ExceptionMessage $_.Exception.Message `\n                    -ExceptionObject $downloadURL `\n                    -ErrorId FailedToDownload `\n                    -ErrorCategory InvalidOperation        \n    }\n}\n\nfunction ThrowError\n{\n    param\n    (        \n        [parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.Management.Automation.PSCmdlet]\n        $CallerPSCmdlet,\n\n        [parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.String]        \n        $ExceptionName,\n\n        [parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.String]\n        $ExceptionMessage,\n        \n        [System.Object]\n        $ExceptionObject,\n        \n        [parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.String]\n        $ErrorId,\n\n        [parameter(Mandatory = $true)]\n        [ValidateNotNull()]\n        [System.Management.Automation.ErrorCategory]\n        $ErrorCategory\n    )\n        \n    $exception = New-Object $ExceptionName $ExceptionMessage;\n    $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $ErrorId, $ErrorCategory, $ExceptionObject    \n    $CallerPSCmdlet.ThrowTerminatingError($errorRecord)\n}\n\nfunction CheckDiskSpace\n{\n    param\n\t(\n\t\t[parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.String]        \n    \t$Destination, \n\t\t\n\t\t[parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.String]        \n    \t$URL\n\t)\n\n    $size = 0\n\n    if($URL.StartsWith(\"https://\"))\n    {\n        $response = Get-HttpResponse -Uri $URL\n        $size = $response.Result.Content.Headers.ContentLength        \n    }\n\n    $parent = Split-Path $Destination -Parent\n    $Drive = (Get-Item $parent).PSDrive.Name\n    $getDriveSpace = get-ciminstance win32_logicaldisk | Where-Object {$_.DeviceID -match $Drive} | % Freespace\n\n    $contentLengthInMB = [math]::Round($size/1mb, 2)\n    $driveSpaceInIMB = [math]::Round($getDriveSpace/1mb, 2)\n\n    Write-Verbose \"Download size: $($contentLengthInMB)MB\"\n    Write-Verbose \"Free space on the drive: $($driveSpaceInIMB)MB\"\n\n    if($size -ge ($getDriveSpace * 0.95))\n    {\n        Write-Error \"Not enough space to save the file\"\n        return $false\n    }\n\n    return $true\n}\n\nfunction VerifyHashCheck\n{\n    param\n\t(\n\t\t[parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.String]        \n    \t$Destination, \n\t\t\n\t\t[parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.String]        \n    \t$hash\n\t)\n\n    Write-Verbose \"Verifying Hash of the downloaded file.\"\n\n    $fileHash = Get-FileHash -Path $Destination `\n                                -Algorithm SHA256\n    \n    if($fileHash.Psobject.properties.name -Contains \"Hash\")\n    {\n        $fileSha256 = $fileHash.Hash\n    }\n    else\n    {\n        Write-Verbose \"Hash for the original file not available.\"\n        return $false\n    }\n\n    return ($hash -ieq $fileSha256)\n}\n\nfunction Test-AdminPrivilege\n{\n    [CmdletBinding()]\n    [OutputType([bool])]\n    Param()\n\n    $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()\n    $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)\n \n    # Get the security principal for the Administrator role\n    $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator\n \n    # Check to see if we are currently running \"as Administrator\"\n    return ($myWindowsPrincipal.IsInRole($adminRole))\n}\n\nfunction IsNanoServer\n{\n    if ($script:isNanoServerInitialized)\n    {\n        return $script:isNanoServer\n    }\n    else\n    {\n        $operatingSystem = Get-CimInstance -ClassName win32_operatingsystem\n        $systemSKU = $operatingSystem.OperatingSystemSKU\n        $script:isNanoServer = ($systemSKU -eq 109) -or ($systemSKU -eq 144) -or ($systemSKU -eq 143)\n        $script:isNanoServerInitialized = $true\n        return $script:isNanoServer\n    }\n}\n\nfunction IsClient\n{\n\n}\n\nfunction Install-NuGetClientBinary\n{\n    [CmdletBinding(SupportsShouldProcess = $true)]\n    param\n    (\n        [parameter(Mandatory = $true)]\n        [ValidateNotNullOrEmpty()]\n        [System.Management.Automation.PSCmdlet]\n        $CallerPSCmdlet,\n\n        [parameter()]\n        [switch]\n        $Force\n    )\n\n    if($script:NuGetProvider)\n    {\n        return\n    }\n\n    $InstallNuGetProviderShouldContinueQuery = \"DockerMsftProvider requires NuGet provider. The NuGet provider must be available in '{0}' or '{1}'. You can also install the NuGet provider by running 'Install-PackageProvider -Name NuGet -Force'. Do you want DockerMsftProvider to install and import the NuGet provider now?\"\n    $InstallNuGetProviderShouldContinueCaption = \"NuGet provider is required to continue\"\n    $CouldNotInstallNuGetProvider = \"NuGet provider is required. Please ensure that NuGet provider is installed.\"\n    $DownloadingNugetProvider = \"Installing NuGet provider.\"\n\n    $bootstrapNuGetProvider = (-not $script:NuGetProvider)\n\n    if($bootstrapNuGetProvider)\n    {\n        # Bootstrap the NuGet provider only if it is not available.\n        # By default PackageManagement loads the latest version of the NuGet provider.\n        $nugetProvider = PackageManagement\\Get-PackageProvider -ErrorAction SilentlyContinue -WarningAction SilentlyContinue |\n                            Microsoft.PowerShell.Core\\Where-Object {$_.Name -eq $script:NuGetProviderName}\n        if($nugetProvider)\n        {\n            $script:NuGetProvider = $nugetProvider\n            $bootstrapNuGetProvider = $false\n\n            return\n        }\n        else\n        {\n            $nugetProvider = PackageManagement\\Get-PackageProvider -ListAvailable -ErrorAction SilentlyContinue -WarningAction SilentlyContinue |\n                            Microsoft.PowerShell.Core\\Where-Object {$_.Name -eq $script:NuGetProviderName}\n\n            if($nugetProvider)\n            {\n                $null = PackageManagement\\Import-PackageProvider -Name $script:NuGetProviderName -Force                \n                $nugetProvider = PackageManagement\\Get-PackageProvider -ErrorAction SilentlyContinue -WarningAction SilentlyContinue |\n                                    Microsoft.PowerShell.Core\\Where-Object {$_.Name -eq $script:NuGetProviderName}\n                if($nugetProvider)\n                {\n                    $script:NuGetProvider = $nugetProvider\n                    $bootstrapNuGetProvider = $false\n\n                    return\n                }\n            }\n        }\n    }\n\n    # We should prompt only once for bootstrapping the NuGet provider\n    \n    # Should continue message for bootstrapping only NuGet provider\n    $shouldContinueQueryMessage = $InstallNuGetProviderShouldContinueQuery -f @($script:NuGetBinaryProgramDataPath,$script:NuGetBinaryLocalAppDataPath)\n    $shouldContinueCaption = $InstallNuGetProviderShouldContinueCaption\n\n    if($Force -or $request.ShouldContinue($shouldContinueQueryMessage, $shouldContinueCaption))\n    {\n        if($bootstrapNuGetProvider)\n        {\n            Write-Verbose -Message $DownloadingNugetProvider\n\n            $scope = 'CurrentUser'\n            if(Test-AdminPrivilege)\n            {\n                $scope = 'AllUsers'\n            }\n\n            # Bootstrap the NuGet provider\n            $null = PackageManagement\\Install-PackageProvider -Name $script:NuGetProviderName `\n                                                              -Scope $scope `\n                                                              -Force\n\n            # Force import ensures that nuget provider with minimum version got loaded.\n            $null = PackageManagement\\Import-PackageProvider -Name $script:NuGetProviderName `\n                                                             -Force\n\n            $nugetProvider = PackageManagement\\Get-PackageProvider -Name $script:NuGetProviderName\n\n            if ($nugetProvider)\n            {\n                $script:NuGetProvider = $nugetProvider\n            }\n        }\n    }\n\n    $message = $null\n    $errorId = $null\n    $failedToBootstrapNuGetProvider = $false\n\n    if($bootstrapNuGetProvider -and -not $script:NuGetProvider)\n    {\n        $failedToBootstrapNuGetProvider = $true\n\n        $message = $CouldNotInstallNuGetProvider\n        $errorId = 'CouldNotInstallNuGetProvider'\n    }\n\n    # Throw the error message if one of the above conditions are met\n    if($message -and $errorId)\n    {\n        ThrowError -ExceptionName \"System.InvalidOperationException\" `\n                    -ExceptionMessage $message `\n                    -ErrorId $errorId `\n                    -CallerPSCmdlet $CallerPSCmdlet `\n                    -ErrorCategory InvalidOperation\n    }\n}\n\n#endregion\n"
  },
  {
    "path": "LICENSE",
    "content": "DockerMsftProvider\n\nCopyright (c) Microsoft Corporation\n\nAll rights reserved.\n\nThe MIT License (MIT)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "## IMPORTANT - THIS PROVIDER IS NOW DEPRECATED\nAs of May 23rd 2023 the backing service for this provider has been shutdown. You can find alternative options at <a href=\"https://learn.microsoft.com/en-us/virtualization/windowscontainers/quick-start/set-up-environment?tabs=dockerce#windows-server-1\">Windows Container Documentation - Setup Environment</a>.\n\nFor more information on the deprecation  please see the following blog posts:\n[Updates to the Windows Container Runtime support](https://techcommunity.microsoft.com/t5/containers/updates-to-the-windows-container-runtime-support/ba-p/2788799)\n[Reminder - Updates to Windows Container Runtime Support](https://techcommunity.microsoft.com/t5/containers/reminder-updates-to-windows-container-runtime-support/ba-p/3620989)\n\nIn the near future this repo will be marked archived. \n\n#### Preserving the original  readme contents:\n\n---\n\n\n### Introduction\n#### Install a Docker image from the online Package repository\n\nThe Docker installer for Windows is now available in an online package repository.  They can be found and installed using the Docker provider of PackageManagement (a.k.a. <a href=\"http://www.oneget.org\">OneGet</a>) PowerShell module.  **The provider needs to be installed before using it.** The following PowerShell cmdlets can be used to install the provider.\n\n##### Step 1: Install the OneGet docker provider\n\n1. `Import-Module -Name DockerMsftProvider -Force`\n2. `Import-Packageprovider -Name DockerMsftProvider -Force`\n\n##### Step 2: Install Docker\n*New installation:*  \n`Install-Package -Name docker -ProviderName DockerMsftProvider -Verbose`  \n\n*Upgrade to the latest version of docker:*  \n`Install-Package -Name docker -ProviderName DockerMsftProvider -Verbose -Update`\n\nOnce the provider is installed and imported, you can search, download, or install Docker using OneGet PowerShell cmdlets:\n* Find-Package\n* Save-Package\n* Install-Package\n* Uninstall-Package\n* Get-Package\n\n#### Register a source\n\n##### Register an URL to be used with DockerMsftProvider\n\tRegister-PackageSource -ProviderName DockerMsftProvider -Name AlternateSource -Location https://contoso.com/metaData.json\n\n##### Enlist all the registered sources\n\tGet-PackageSource -ProviderName DockerMsftProvider\n\n#### Search a Docker installer \n\n##### Example 1: Find the latest version of all available Docker installers. \n\tFind-Package -providerName DockerMsftProvider\n   \n##### Example 2: Search by version, according to -RequiredVersion, -MinimumVersion, and -MaximumVersion requirements. With -AllVersions parameter, all available versions of Docker installers are returned. Without it, only the latest version is returned.\n    Find-Package -providerName DockerMsftProvider -AllVersions\n\n#### Install docker\n\n##### Example 1: Install the latest version of docker to the local machine.\n\tInstall-Package -Name docker -ProviderName DockerMsftProvider -Verbose\n\n##### Example 2: Install docker with pipeline result from the search cmdlets.\t\n\tFind-Package -ProviderName DockerMsftProvider | Install-Package -Verbose\n\n#### Download Docker\nYou can download and save Docker installer without installation, using Save-Package. This cmdlet accepts pipeline result from the search cmdlets. If you have multiple sources, please provide the source for download.\n\n##### Example 1: Download and save Docker installer to a directory that matches the wildcard path. The latest version will be saved if you do not specify the version requirements.\t\n\tSave-Package -ProviderName DockerMsftProvider -Name Docker -Path .\\temp -MinimumVersion 1.2.3\n\n##### Example 2: Download and save Docker installer from the search cmdlets.\n\tFind-package -ProviderName DockerMsftProvider | Save-Package -Path .\n\n#### Get docker\n\n\n##### Example 1: Inventory docker installation on the local machine.\n\t Get-Package -ProviderName DockerMsftProvider\n\n#### Uninstall docker\nUninstalls Docker from the local machine.\n\n##### Example 1: Uninstall docker from the local machine.\n\tUninstall-Package -ProviderName DockerMsftProvider -Name dOcKeR -Verbose\n\n#### Update docker\nUpdates current installation of docker with the requested version\n\n##### Example 1: Update docker\n\tInstall-Package -Name docker -ProviderName DockerMsftProvider -Verbose -Update\n\n### Manual Steps\n    Once docker is installed, you will need to restart the machine\n    After the machine is restarted, docker service needs to be in the running state\n\t\n\tAfter you have installed the required KB (KB3176936 or higher) you will need to restart the machine \n\n### Version\n1.0.0.8\n\n### Version History\n\n#### 0.1.0.0\n\tInitial release\n\n#### 0.1.0.1\n\tBug fixes\n\n#### 0.1.0.2\n\tBug fixes\n\n#### 0.1.0.3\n\tBug fixes\n\n#### 1.0.0.0\n\tPublic release\n\n#### 1.0.0.1\n\tAdded OS version check instead of KB check\n\n#### 1.0.0.2\n\tUpdated the restart message after install\n\tUpdate the logging while uninstall\n\t\n#### 1.0.0.6\n\tFixed a bug in how dockerd was being registered as a service\n\n#### 1.0.0.7\n\tFixed a bug where system env vars would be mangled when installing/uninstalling Docker on top of another.\n\tFixed readme instruction formatting for easier copy/paste/execute\n\n#### 1.0.0.8\n\tFixed a bug where installation of Docker fails over a slow network connection.\n\tAdded more helpful error text towards failed installation attempts on Windows 10 client machines.\n\n### Dependencies\n* 1. Nuget binaries\n* 2. Update: KB3176936 or later needs to be installed on your machine\n\n### Not supported scenarios\n* 1. We use BITs for downloading purposes. Currently the following scenarios are not supported by BITs:\n\t* 1.1. Behind a proxy\n\t* 1.2. Powershell Direct\n\t* 1.3. SSH remoting\n\t* Note: Please use WinRM based Powershell Remoting.\n"
  }
]