#
# GitHub Dekstop post snapshot script
# https://github.com/turboapps/turbome/tree/master/github/githubdesktop
#
# Licensed under the Apache License, Version 2.0
# http://www.apache.org/licenses/LICENSE-2.0

#
# Edit XAPPL
#

Import-Module Turbo

$XappPath = 'C:\output\Snapshot.xappl'
$xappl = Read-XAPPL $XappPath

Remove-StartupFiles $xappl
Add-StartupFile $xappl -File "@APPDATALOCAL@\GitHubDesktop\GitHubDesktop.exe" -AutoStart

Save-XAPPL $xappl $XappPath

Add chromium support vm setting

#
# GitHub Dekstop post snapshot script
# https://github.com/turboapps/turbome/tree/master/github/githubdesktop
#
# Licensed under the Apache License, Version 2.0
# http://www.apache.org/licenses/LICENSE-2.0

#
# Edit XAPPL
#

Import-Module Turbo

$XappPath = 'C:\output\Snapshot.xappl'
$xappl = Read-XAPPL $XappPath

Remove-StartupFiles $xappl
Add-StartupFile $xappl -File "@APPDATALOCAL@\GitHubDesktop\GitHubDesktop.exe" -AutoStart

Set-VirtualizationSetting($xappl, "chromiumSupport", "True")

Save-XAPPL $xappl $XappPath


# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel and Kyle Kastner
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/

$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
$GET_PIP_PATH = "C:\get-pip.py"

function InstallPip ($python_home) {
    $pip_path = $python_home + "/Scripts/pip.exe"
    $python_path = $python_home + "/python.exe"
    if (-not(Test-Path $pip_path)) {
        Write-Host "Installing pip..."
        $webclient = New-Object System.Net.WebClient
        $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
        Write-Host "Executing:" $python_path $GET_PIP_PATH
        Start-Process -FilePath "$python_path" -ArgumentList "$GET_PIP_PATH" -Wait -Passthru
    } else {
        Write-Host "pip already installed."
    }
}

function InstallPackage ($python_home, $pkg) {
    $pip_path = $python_home + "/Scripts/pip.exe"
    & $pip_path install $pkg
}

function main () {
    InstallPip $env:PYTHON
    InstallPackage $env:PYTHON pytest
}

main

Install requirements with pip on appveyor.

# Sample script to install Python and pip under Windows
# Authors: Olivier Grisel and Kyle Kastner
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/

$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py"
$GET_PIP_PATH = "C:\get-pip.py"

function InstallPip ($python_home) {
    $pip_path = $python_home + "/Scripts/pip.exe"
    $python_path = $python_home + "/python.exe"
    if (-not(Test-Path $pip_path)) {
        Write-Host "Installing pip..."
        $webclient = New-Object System.Net.WebClient
        $webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH)
        Write-Host "Executing:" $python_path $GET_PIP_PATH
        Start-Process -FilePath "$python_path" -ArgumentList "$GET_PIP_PATH" -Wait -Passthru
    } else {
        Write-Host "pip already installed."
    }
}

function InstallPackage ($python_home, $pkg) {
    $pip_path = $python_home + "/Scripts/pip.exe"
    & $pip_path install $pkg
}

function InstallRequirements ($python_home, $reqs) {
    $pip_path = $python_home + "/Scripts/pip.exe"
    & $pip_path install -r $reqs
}

function main () {
    InstallPip $env:PYTHON
    InstallReqs $env:PYTHON -r requirements.txt
    InstallPackage $env:PYTHON pytest
}

main


# To use this:
# 1. Enable running scripts (must be run as an administrator):
# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force
# 2. Unblock this file:
# Unblock-File -Path ./configure-windows-10.ps1
# 3. Run the file
# ./configure-windows-10.ps1

# Disable Cortana
# Source: https://gallery.technet.microsoft.com/scriptcenter/How-to-disable-Cortana-on-b44924a4
# License: TechNet terms of use (https://gallery.technet.microsoft.com/scriptcenter/site/How-to-disable-Cortana-on-b44924a4/eulapartial?licenseType=TechNet)
Function DisableCortana {
    $path = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\Windows Search"
    IF (!(Test-Path -Path $path)) {
        New-Item -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows" -Name "Windows Search"
    }
    Set-ItemProperty -Path $path -Name "AllowCortana" -Value 0
    # Restart Explorer to change it immediately
    Stop-Process -name explorer
}
DisableCortana


param($installPath, $toolsPath, $package, $project)

Import-Module (Join-Path $toolsPath Unity3D.DLLs.psd1)

Remove the Unity3D.DLLs PS module if its loaded.

# Copyright (c) 2013 Precision Mojo, LLC.
#
# This file is part of the Unity3D.DLLs project (< URL >) which is distributed under the MIT License.
# Refer to the LICENSE.MIT.md document located in the project directory for licensing terms.

param($installPath, $toolsPath, $package, $project)

# Remove the module if it's loaded
if (Get-Module | ? { $_.Name -eq "Unity3D.DLLs" })
{
	Remove-Module Unity3D.DLLs
}

Import-Module (Join-Path $toolsPath Unity3D.DLLs.psd1)


# TODO: This script should be replaced with wixproj and/or CPack.
# TODO: Add Debug mode to override CompressionLevel with "none".

# Sample command:
# .\build.ps1 -Arch x64 -Version 0.4.0 -PackagePath "c:\tmp\zeal-0.4.0-windows-x64" -SignMsi

param(
    [Parameter(Mandatory=$True)]
    [ValidatePattern("[0-9].[0-9].[0-9]")]
    [string]$Version,

    [Parameter(Mandatory=$True)]
    [ValidateSet('x86', 'x64')]
    [string]$Arch,

    [Parameter(Mandatory=$True)]
    [string]$PackagePath,

    [Switch]$SignMsi
)

$BaseFilename = "zeal-$Version-windows-$Arch"
$WixobjFilename = "$BaseFilename.wixobj"
$MsiFilename = "$BaseFilename.msi"
function CleanUp {
    Remove-Item -Path "$WixobjFilename"

    # We are not going to build patches for now.
    # More infor about wixpdb: https://www.firegiant.com/wix/tutorial/upgrades-and-modularization/patchwork/
    Remove-Item -Path "$BaseFilename.wixpdb"
}

Write-Output "Building $MsiFilename..."

Write-Output "Running candle..."
& candle.exe -nologo -pedantic -wx -arch "$Arch" -dAppVersion="$Version" -dAppPackageDir="$PackagePath" -o "$WixobjFilename" zeal.wxs
if ($LastExitCode -ne 0) {
    CleanUp
    throw "candle failed with exit code $LastExitCode."
}

Write-Output "Running light..."
& light.exe -nologo -pedantic -wx -ext WixUIExtension -o "$MsiFilename" "$WixobjFilename"
if ($LastExitCode -ne 0) {
    CleanUp
    throw "light failed with exit code $LastExitCode."
}

if ($SignMsi) {
    $KeyName = "Open Source Developer, Oleg Shparber"
    $Description = "Zeal $Version Installer"
    $Url = "https://zealdocs.org"
    $TimestampServerUrl = "http://timestamp.comodoca.com/authenticode"

    Write-Output "Signing $MsiFilename..."
    & signtool sign /v /n "$KeyName" /d "$Description" /du "$Url" /t "$TimestampServerUrl" "$MsiFilename"
    if ($LastExitCode -ne 0) {
        CleanUp
        throw "signtool failed with exit code $LastExitCode."
    }
}

CleanUp


Write-Host "Installing chocolatey"
Set-ExecutionPolicy Unrestricted
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

Write-Host "Installing git"
choco install -y git.install

((New-Object System.Net.WebClient).DownloadFile('https://github.com/ctfhacker/windows-setup/archive/master.zip', 'C:\Windows\Temp\master.zip'))

cd C:\Windows\Temp\
[System.IO.Compression.ZipFile]::ExtractToDirectory('master.zip', 'windows-setup')
cd windows-setup

Get-ChildItem | ForEach-Object {
    Write-Host "Executing " + $_.FullName
    & $_.FullName
}

# Write-Host "Rebooting.."
# shutdown /r /t 0

Use unzip instead of .NET

Write-Host "Installing chocolatey"
Set-ExecutionPolicy Unrestricted
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

Write-Host "Installing unzip"
choco install -y unzip

((New-Object System.Net.WebClient).DownloadFile('https://github.com/ctfhacker/windows-setup/archive/master.zip', 'C:\Windows\Temp\master.zip'))

cd C:\Windows\Temp\
unzip master.zip
cd windows-setup-master

Get-ChildItem | ForEach-Object {
    Write-Host "Executing " + $_.FullName
    & $_.FullName
}

# Write-Host "Rebooting.."
# shutdown /r /t 0


$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition

& "$ScriptPath\PowerShellProfile\Microsoft.PowerShell_profile.ps1"

## Development Tools for .NET

choco install VisualStudioCommunity2013 -packageParameters "/Features:WebTools"

choco install webpi
choco install webpicmd

choco install IIS-WebServerRole -source windowsfeatures
choco install IIS-ASPNET45 -source windowsfeatures

choco install SQLManagementStudio -source webpi

Make sure IIS websockets is installed

$ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition

& "$ScriptPath\PowerShellProfile\Microsoft.PowerShell_profile.ps1"

## Development Tools for .NET

choco install VisualStudioCommunity2013 -packageParameters "/Features:WebTools"

choco install webpi
choco install webpicmd

choco install IIS-WebServerRole -source windowsfeatures
choco install IIS-ASPNET45 -source windowsfeatures
choco install IIS-WebSockets -source windowsfeatures

choco install SQLManagementStudio -source webpi


mkdir -p C:\registry-v2
docker run -d -p 5000:5000 -v "C:\registry-v2:C:\registry" stefanscherer/registry-windows:2.4.1

Update registry 2.5.1, but still does not work inside a container

mkdir -p C:\registry-v2
docker run -d -p 5000:5000 -v "C:\registry-v2:C:\registry" stefanscherer/registry-windows:2.5.1


Describe "New-Object" {
    It "should create an object with 4 fields" {
	$o = New-Object psobject
	$val = $o.GetType()

	$val.IsPublic       | Should Not BeNullOrEmpty
	$val.Name           | Should Not BeNullOrEmpty
	$val.IsSerializable | Should Not BeNullOrEmpty
	$val.BaseType       | Should Not BeNullOrEmpty

	$val.IsPublic       | Should Be $true
	$val.IsSerializable | Should Be $false
	$val.Name           | Should Be 'PSCustomObject'
	$val.BaseType       | Should Be 'System.Object'
    }

    It "should create an object with using Property switch" {
    $hash = @{
        FirstVal = 'test1'
        SecondVal = 'test2'
    }
	$o = New-Object psobject -Property $hash

	$o.FirstVal     | Should Be 'test1'
	$o.SecondVal    | Should Be 'test2'
    }

    It "should create a .Net object with using ArgumentList switch" {
	$o = New-Object -TypeName System.Version -ArgumentList "1.2.3.4"
    $val = $o.GetType()

	$o      | Should Be "1.2.3.4"

    $val.IsPublic       | Should Be $true
	$val.IsSerializable | Should Be $false
	$val.Name           | Should Be 'Version'
	$val.BaseType       | Should Be 'System.Object'
    }
}

Modify Pester test for New-Object

Describe "New-Object" {
    It "should create an object with 4 fields" {
        $o = New-Object psobject
	    $val = $o.GetType()

	    $val.IsPublic       | Should Not BeNullOrEmpty
	    $val.Name           | Should Not BeNullOrEmpty
	    $val.IsSerializable | Should Not BeNullOrEmpty
	    $val.BaseType       | Should Not BeNullOrEmpty

	    $val.IsPublic       | Should Be $true
	    $val.IsSerializable | Should Be $false
	    $val.Name           | Should Be 'PSCustomObject'
	    $val.BaseType       | Should Be 'System.Object'
    }

    It "should create an object with using Property switch" {
        $hash = @{
            FirstVal = 'test1'
            SecondVal = 'test2'
        }
	    $o = New-Object psobject -Property $hash

	    $o.FirstVal     | Should Be 'test1'
	    $o.SecondVal    | Should Be 'test2'
    }

    It "should create a .Net object with using ArgumentList switch" {
	    $o = New-Object -TypeName System.Version -ArgumentList "1.2.3.4"
        $o.GetType() | Should Be ([System.Version])

	    $o      | Should Be "1.2.3.4"
    }
}


Add a script to install the PowerShell profile

# Overwrite the current PowerShell profile, and hardlink that path to the
# profile in this repo.
Remove-Item $profile
New-Item -ItemType HardLink -Path $profile -Target "$PSScriptRoot\Microsoft.PowerShell_profile.ps1"


$ErrorActionPreference = "stop"
New-Item -ItemType Directory -Path "$env:PKG_PATH/etc/", "$env:PKG_PATH/etc/dcos-adminrouter/"
New-Item -ItemType Directory -Path "$env:PKG_PATH/etc/dcos-adminrouter/conf/", "$env:PKG_PATH/etc/dcos-adminrouter/logs/"
New-Item -ItemType Directory -Path "$env:PKG_PATH/bin/", "$env:PKG_PATH/bin/dcos-adminrouter/"
New-Item -ItemType Directory "c:\tmp"

Add-Type -AssemblyName System.IO.Compression.FileSystem
function Unzip {
    param([string]$zipfile, [string]$outpath)
    [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}

Unzip "c:\pkg\src\OpenResty\openresty-1.15.8.2-win64.zip" "c:/tmp/openresty"

ls "C:\pkg\build\extra\src\"

Copy-Item -Recurse -Path "c:\tmp\openresty\openresty-1.15.8.2-win64\*" "$env:PKG_PATH\bin\dcos-adminrouter\"
Copy-Item -Recurse -Path "C:\pkg\build\extra\src\*" "$env:PKG_PATH\etc\dcos-adminrouter\conf\"
Copy-Item "$env:PKG_PATH\etc\dcos-adminrouter\conf\nginx.agent.conf" "$env:PKG_PATH\etc\dcos-adminrouter\conf\nginx.conf"

Correct default config file name for nginx

$ErrorActionPreference = "stop"
New-Item -ItemType Directory -Path "$env:PKG_PATH/etc/", "$env:PKG_PATH/etc/dcos-adminrouter/"
New-Item -ItemType Directory -Path "$env:PKG_PATH/etc/dcos-adminrouter/conf/", "$env:PKG_PATH/etc/dcos-adminrouter/logs/"
New-Item -ItemType Directory -Path "$env:PKG_PATH/bin/", "$env:PKG_PATH/bin/dcos-adminrouter/"
New-Item -ItemType Directory "c:\tmp"

Add-Type -AssemblyName System.IO.Compression.FileSystem
function Unzip {
    param([string]$zipfile, [string]$outpath)
    [System.IO.Compression.ZipFile]::ExtractToDirectory($zipfile, $outpath)
}

Unzip "c:\pkg\src\OpenResty\openresty-1.15.8.2-win64.zip" "c:/tmp/openresty"

ls "C:\pkg\build\extra\src\"

Copy-Item -Recurse -Path "c:\tmp\openresty\openresty-1.15.8.2-win64\*" "$env:PKG_PATH\bin\dcos-adminrouter\"
Copy-Item -Recurse -Path "C:\pkg\build\extra\src\*" "$env:PKG_PATH\etc\dcos-adminrouter\conf\"
Copy-Item "$env:PKG_PATH\etc\dcos-adminrouter\conf\nginx.windows.agent.conf" "$env:PKG_PATH\etc\dcos-adminrouter\conf\nginx.conf"


Add script to update MRTK version across all files

<#
.SYNOPSIS
    Updates Mixed Reality Toolkit version (i.e. major.minor.patch) across all known files.
#>
param(
    [Parameter(Position=0,mandatory=$true)]
    [string]$NewVersion
#     [ValidatePattern("^\d+\.\d+\.\d+$")]
#     [string]$Version,
)

Push-Location  # save current working directory

Set-Location $PSScriptRoot
$GitRoot = (git rev-parse --show-toplevel) | Out-String
$GitRoot = ($GitRoot -replace "/", "\").Trim()

$FullProductName = "Microsoft Mixed Reality Toolkit"

$Errors = @()

foreach ($file in (Get-ChildItem -Path $GitRoot -Recurse))
{
    if ($file.Name -eq "version.txt")
    {
        $contents = Get-Content -Path $file.FullName
        $pattern = "(?<=Microsoft Mixed Reality Toolkit\s+)(\d+\.\d+\.\d+)"
        $match = [regex]::Match($contents, $pattern)
        if ($match.Success)
        {
            $FromVersion = $match.captures.groups[1].ToString()
            if ($FromVersion -eq $NewVersion)
            {
                Write-Host "$($file.FullName): version up to date ($NewVersion)"
            }
            else
            {
                Write-Host "$($file.FullName): updating version from $FromVersion to $NewVersion"
                $contents = $contents -replace $pattern, $NewVersion
                $contents | Out-File -FilePath $file.FullName -Encoding UTF8
            }
        }
        else
        {
            $errors += "$($file.FullName): pattern not found: $pattern"
        }
    }
}

Pop-Location  # restore original working directory

if ($errors)
{
    Write-Host -ForegroundColor Red "Errors:"
    foreach ($line in $errors)
    {
        Write-Host  -ForegroundColor Red "    $line"
    }
    exit 1
}
else
{
    Write-Host
    Write-Host -ForegroundColor Green "Version updated to $NewVersion. Please review all changes before submitting."
    Write-Host
    exit 0
}


$publishVersion = $Env:GitVersion_MajorMinorPatch+"."+$Env:GitVersion_BuildMetaData

# Regular expression pattern to find the version in the build number
# and then apply it to the assemblies
$versionRegex = "\d+\.\d+\.\d+\.\d+"

$vsixManifestSearchPattern = "./source.extension.vsixmanifest"
$vsixManifestCollection = (Get-ChildItem $vsixManifestSearchPattern -Recurse)

foreach($file in $vsixManifestCollection)
{
    $filecontent = Get-Content($file)
    attrib $file -r
    $filecontent -replace $versionRegex, $publishVersion | Out-File $file -Encoding utf8
    "Update version in VSIX manifest to $publishVersion"| Write-Host -ForegroundColor White
}

Update PS script to improve version generation

if ($env:APPVEYOR_PULL_REQUEST_NUMBER)
{
    # version for pull requests
    $publishVersion = $Env:GitVersion_MajorMinorPatch+"."+$Env:GitVersion_CommitsSinceVersionSource
}
else
{
    # version for commits other than PRs
    $publishVersion = $Env:GitVersion_AssemblySemVer
}

# Regular expression pattern to find the version in the build number
# and then apply it to the assemblies
$versionRegex = "\d+\.\d+\.\d+\.\d+"

$vsixManifestSearchPattern = "./source.extension.vsixmanifest"
$vsixManifestCollection = (Get-ChildItem $vsixManifestSearchPattern -Recurse)

foreach($file in $vsixManifestCollection)
{
    $filecontent = Get-Content($file)
    attrib $file -r
    $filecontent -replace $versionRegex, $publishVersion | Out-File $file -Encoding utf8
    "Update version in VSIX manifest to $publishVersion"| Write-Host -ForegroundColor White
}


@{
    IncludeRules = @('*')

    Rules = @{
        # The statement assignment alignment check applies to the hashtable
        # assignment itself and not just its properties.
        PSAlignAssignmentStatement = @{
            Enable                      = $false
            CheckHashtable              = $true
        }

        PSPlaceCloseBrace = @{
            Enable                      = $true
            IgnoreOneLineBlock          = $true
            NewLineAfter                = $false
            NoEmptyLineBefore           = $false
        }

        PSPlaceOpenBrace = @{
            Enable                      = $true
            IgnoreOneLineBlock          = $true
            NewLineAfter                = $true
            OnSameLine                  = $true
        }

        PSProvideCommentHelp = @{
            Enable                      = $true
            BlockComment                = $true
            ExportedOnly                = $true
            Placement                   = 'begin'
            VSCodeSnippetCorrection     = $false
        }

        PSUseConsistentIndentation = @{
            Enable                      = $true
            IndentationSize             = 4
            Kind                        = 'space'
        }

        # CheckOperator doesn't work with aligned hashtable assignment
        # statements (GitHub Issue #769).
        PSUseConsistentWhitespace = @{
            Enable                      = $true
            CheckOpenBrace              = $true
            CheckOpenParen              = $true
            CheckOperator               = $false
            CheckSeparator              = $true
        }
    }
}

Add new PSScriptAnalyzer rule options

@{
    IncludeRules = @('*')

    Rules = @{
        # The statement assignment alignment check applies to the hashtable
        # assignment itself and not just its properties.
        PSAlignAssignmentStatement = @{
            Enable                      = $false
            CheckHashtable              = $true
        }

        PSPlaceCloseBrace = @{
            Enable                      = $true
            IgnoreOneLineBlock          = $true
            NewLineAfter                = $false
            NoEmptyLineBefore           = $false
        }

        PSPlaceOpenBrace = @{
            Enable                      = $true
            IgnoreOneLineBlock          = $true
            NewLineAfter                = $true
            OnSameLine                  = $true
        }

        PSProvideCommentHelp = @{
            Enable                      = $true
            BlockComment                = $true
            ExportedOnly                = $true
            Placement                   = 'begin'
            VSCodeSnippetCorrection     = $false
        }

        PSUseConsistentIndentation = @{
            Enable                      = $true
            IndentationSize             = 4
            Kind                        = 'space'
            PipelineIndentation         = 'IncreaseIndentationForFirstPipeline'
        }

        # CheckOperator doesn't work with aligned hashtable assignment
        # statements (GitHub Issue #769).
        PSUseConsistentWhitespace = @{
            Enable                      = $true
            CheckInnerBrace             = $true
            CheckOpenBrace              = $true
            CheckOpenParen              = $true
            CheckOperator               = $false
            CheckPipe                   = $true
            CheckSeparator              = $true
        }
    }
}


# Copyright(c) 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

dotnet restore
dotnet test --test-adapter-path:. --logger:junit

Extend Vision Test timeout, because it has been timing out lately.

# Copyright(c) 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
Import-Module ..\..\..\BuildTools.psm1

Set-TestTimeout 600

dotnet restore
dotnet test --test-adapter-path:. --logger:junit


param($installPath, $toolsPath, $package, $project)

foreach ($reference in $project.Object.References)
{
	switch -regex ($reference.Name.ToLowerInvariant())
	{
	"^tvl\.visualstudio\.outputwindow.interfaces$"
		{
			$reference.CopyLocal = $false;
		}
	default
		{
			# ignore
		}
	}
}

Fix the regex used for detecting the Output Window reference

param($installPath, $toolsPath, $package, $project)

foreach ($reference in $project.Object.References)
{
	switch -regex ($reference.Name.ToLowerInvariant())
	{
	"^tvl\.visualstudio\.outputwindow\.interfaces$"
		{
			$reference.CopyLocal = $false;
		}
	default
		{
			# ignore
		}
	}
}


$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'

$dockerVersion="18.02.0-ce"

Write-Host "Installing Docker CLI $dockerVersion"
docker pull stefanscherer/docker-cli-windows:$dockerVersion-2016
docker create stefanscherer/docker-cli-windows:$dockerVersion-2016
docker cp "$(docker ps -ql):docker.exe" $env:TEMP\docker.exe
cp $env:TEMP\docker.exe "$env:ProgramFiles\docker\docker.exe"

Write-Host "Activating experimental features"
$configJson = "$env:USERPROFILE\.docker\config.json"
$config = @{}
if (Test-Path $configJson) {
 $config = (Get-Content $configJson) -join "`n" | ConvertFrom-Json
}
$config = $config | Add-Member(@{ experimental = 'enabled' }) -Force -PassThru
$config | ConvertTo-Json | Set-Content $configJson -Encoding Ascii

docker version

Remove 2016 tag, order in manifest list has been fixed

$ErrorActionPreference = 'Stop'
$ProgressPreference = 'SilentlyContinue'

$dockerVersion="18.02.0-ce"

Write-Host "Installing Docker CLI $dockerVersion"
docker pull stefanscherer/docker-cli-windows:$dockerVersion
docker create stefanscherer/docker-cli-windows:$dockerVersion
docker cp "$(docker ps -ql):docker.exe" $env:TEMP\docker.exe
cp $env:TEMP\docker.exe "$env:ProgramFiles\docker\docker.exe"

Write-Host "Activating experimental features"
$configJson = "$env:USERPROFILE\.docker\config.json"
$config = @{}
if (Test-Path $configJson) {
 $config = (Get-Content $configJson) -join "`n" | ConvertFrom-Json
}
$config = $config | Add-Member(@{ experimental = 'enabled' }) -Force -PassThru
$config | ConvertTo-Json | Set-Content $configJson -Encoding Ascii

docker version


Task Default -depends Test

Task Build {
   Exec { msbuild "NPloy.sln" }
   Exec { & copy NPloy.Console\bin\debug\NPloy.Console.exe NPloy.Console\bin\debug\NPloy.exe}
   Exec { & .\packages\LibZ.Bootstrap.1.0.3.7\tools\libz.exe inject-dll --assembly NPloy.Console\bin\debug\NPloy.exe --include NPloy.Console\bin\debug\*.dll --move }
   Exec { & xcopy /y /e NPloy.Console\bin\debug\nploy.exe ..\install\}
}

Task UnitTest {
   Exec { & packages\NUnit.Runners.2.6.3\tools\nunit-console.exe NPloy.Console.UnitTests\bin\debug\NPloy.Console.UnitTests.dll /xml=UnitTestResult.xml  }
}

Task IntegrationTest {
   Exec { & packages\NUnit.Runners.2.6.3\tools\nunit-console.exe NPloy.Console.IntegrationTests\bin\debug\NPloy.Console.IntegrationTests.dll /xml=IntegrationTestResult.xml  }
}

Task Test -depends Build, UnitTest  {
}

Task Pack -depends Test {
	Exec { & .nuget\nuget pack NPloy.Console\NPloy.Console.nuspec -NoPackageAnalysis -OutputDirectory ..\packages }
}

Create package directory if not exists

Task Default -depends Test

Task Build {
   Exec { msbuild "NPloy.sln" }
   Exec { & copy NPloy.Console\bin\debug\NPloy.Console.exe NPloy.Console\bin\debug\NPloy.exe}
   Exec { & .\packages\LibZ.Bootstrap.1.0.3.7\tools\libz.exe inject-dll --assembly NPloy.Console\bin\debug\NPloy.exe --include NPloy.Console\bin\debug\*.dll --move }
   Exec { & xcopy /y /e NPloy.Console\bin\debug\nploy.exe ..\install\}
}

Task UnitTest {
   Exec { & packages\NUnit.Runners.2.6.3\tools\nunit-console.exe NPloy.Console.UnitTests\bin\debug\NPloy.Console.UnitTests.dll /xml=UnitTestResult.xml  }
}

Task IntegrationTest {
   Exec { & packages\NUnit.Runners.2.6.3\tools\nunit-console.exe NPloy.Console.IntegrationTests\bin\debug\NPloy.Console.IntegrationTests.dll /xml=IntegrationTestResult.xml  }
}

Task Test -depends Build, UnitTest  {
}

Task Pack -depends Test {
	Exec {
		New-Item -ItemType Directory -Force -Path ..\packages
		& .nuget\nuget pack NPloy.Console\NPloy.Console.nuspec -NoPackageAnalysis -OutputDirectory ..\packages
		}
}


### Install handy tools and apps for my dev machine
### Run this script from an administrative shell

Set-ExecutionPolicy RemoteSigned

# Install Chocolatey
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

# Install some software with Chocolatey
choco install -y 7zip
choco install -y dotnetcore-sdk
choco install -y git
#choco install -y github-desktop    # Github Desktop gets updates so often that it's hard for the Chocolatey package to keep up
choco install -y gitkraken
choco install -y googlechrome
choco install -y hyper
choco install -y keepass
choco install -y linqpad
choco install -y nodejs-lts
choco install -y notepadplusplus
choco install -y poshgit
choco install -y postman
choco install -y rdcman
#choco install -y slack             # Slack gets updates so often that it's annoying to have Chocolatey reinstall it each time
choco install -y sql-server-management-studio
#choco install -y toggl             # The Toggl Desktop Chocolatey package is significantly behind as of May 2017, so I'll install it manually
#choco install -y visualstudiocode  # VS Code gets updates so often that it's hard for the Chocolatey package to keep up
RefreshEnv.cmd

# Install some software with npm
npm install -g @angular/cli
npm install -g typescript

Install Insomnia REST API client

### Install handy tools and apps for my dev machine
### Run this script from an administrative shell

Set-ExecutionPolicy RemoteSigned

# Install Chocolatey
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))

# Install some software with Chocolatey
choco install -y 7zip
choco install -y dotnetcore-sdk
choco install -y git
#choco install -y github-desktop    # Github Desktop gets updates so often that it's hard for the Chocolatey package to keep up
choco install -y gitkraken
choco install -y googlechrome
choco install -y hyper
choco install -y insomnia-rest-api-client
choco install -y keepass
choco install -y linqpad
choco install -y nodejs-lts
choco install -y notepadplusplus
choco install -y poshgit
choco install -y postman
choco install -y rdcman
#choco install -y slack             # Slack gets updates so often that it's annoying to have Chocolatey reinstall it each time
choco install -y sql-server-management-studio
#choco install -y toggl             # The Toggl Desktop Chocolatey package is significantly behind as of May 2017, so I'll install it manually
#choco install -y visualstudiocode  # VS Code gets updates so often that it's hard for the Chocolatey package to keep up
RefreshEnv.cmd

# Install some software with npm
npm install -g @angular/cli
npm install -g typescript


Import-Module PSScriptAnalyzer
$ruleName = "PlaceOpenBrace"

Describe "PlaceOpenBrace" {
    Context "" {
        It "" {
        }
    }
}

Add test for PlaceOpenBrace rule

Import-Module PSScriptAnalyzer
$ruleName = "PSPlaceOpenBrace"

Describe "PlaceOpenBrace on same line" {
    Context "When a open brace is on a new line" {
        BeforeAll{
            $def = @'
function foo ($param1)
{

}
'@
            $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -IncludeRule $ruleName
        }

        It "Should find a violation" {
            $violations.Count | Should Be 1
        }

        It "Should mark only the open brace" {
            $violations[0].Extent.Text | Should Be '{'
        }
    }
}


param(
	[string]$Configuration,
	[string]$Version
)

Write-Host "Configuration: $Configuration"
Write-Host "Version: $Version"

$ErrorActionPreference = "Stop"

Write-Host "Building the NuGet package..."
Start-Process -FilePath "$PSScriptRoot\Nuget.exe" -WorkingDirectory "..\LH.TestObjects\" -Wait -NoNewWindow -ArgumentList "pack -Verbosity Detailed -Prop Configuration=$Configuration"
# & "$PSScriptRoot\Nuget.exe" pack -Verbosity Detailed -Prop Configuration=$Configuration

Write-Host "Creating the website artifacts..."
New-Item "..\_Artifacts\v$Version" -ItemType Directory

Copy-Item "..\License" "..\_Artifacts\v$Version\License.txt"
Copy-Item "..\Logo_128.png" "..\_Artifacts\v$Version\nuget-icon.png"
Copy-Item "..\LH.TestObjects\*.nupkg" "..\_Artifacts\"

Build script - license file name case fix

param(
	[string]$Configuration,
	[string]$Version
)

Write-Host "Configuration: $Configuration"
Write-Host "Version: $Version"

$ErrorActionPreference = "Stop"

Write-Host "Building the NuGet package..."
Start-Process -FilePath "$PSScriptRoot\Nuget.exe" -WorkingDirectory "..\LH.TestObjects\" -Wait -NoNewWindow -ArgumentList "pack -Verbosity Detailed -Prop Configuration=$Configuration"
# & "$PSScriptRoot\Nuget.exe" pack -Verbosity Detailed -Prop Configuration=$Configuration

Write-Host "Creating the website artifacts..."
New-Item "..\_Artifacts\v$Version" -ItemType Directory

Copy-Item "..\License" "..\_Artifacts\v$Version\license.txt"
Copy-Item "..\Logo_128.png" "..\_Artifacts\v$Version\nuget-icon.png"
Copy-Item "..\LH.TestObjects\*.nupkg" "..\_Artifacts\"


@{
    IncludeRules = @(
        'PSPlaceOpenBrace',
        'PSPlaceCloseBrace',
        'PSUseConsistentWhitespace',
        'PSUseConsistentIndentation',
        'PSAlignAssignmentStatement'
    )

    Rules        = @{
        PSPlaceOpenBrace           = @{
            Enable             = $true
            OnSameLine         = $true
            NewLineAfter       = $true
            IgnoreOneLineBlock = $true
        }

        PSPlaceCloseBrace          = @{
            Enable             = $true
            NewLineAfter       = $false
            IgnoreOneLineBlock = $true
            NoEmptyLineBefore  = $false
        }

        PSUseConsistentIndentation = @{
            Enable          = $true
            IndentationSize = 4
        }

        PSUseConsistentWhitespace  = @{
            Enable         = $true
            CheckOpenBrace = $true
            CheckOpenParen = $true
            CheckOperator  = $true
            CheckSeparator = $true
        }

        PSAlignAssignmentStatement = @{
            Enable         = $true
            CheckHashtable = $true
        }
    }
}


param([String]$Version="0.0.0");

ForEach ($category in "Core", "Modules", "Bundles")
{
    ForEach ($folder in (Get-ChildItem -Path $category -Directory))
    {
        dotnet pack $folder.FullName --configuration Release --nologo /p:ContinuousIntegrationBuild=true;
        nuget push "$($folder.FullName)\bin\Release\$($folder.Name).$($Version).nupkg";
        nuget push "$($folder.FullName)\bin\Release\$($folder.Name).$($Version).snupkg";
    }
}

Use dotnet nuget instead of nuget

param([String]$Version="0.0.0");

ForEach ($category in "Core", "Modules", "Bundles")
{
    ForEach ($folder in (Get-ChildItem -Path $category -Directory))
    {
        dotnet pack $folder.FullName --configuration Release --nologo /p:ContinuousIntegrationBuild=true;
        dotnet nuget push "$($folder.FullName)\bin\Release\$($folder.Name).$($Version).nupkg";
        dotnet nuget push "$($folder.FullName)\bin\Release\$($folder.Name).$($Version).snupkg";
    }
}


# List of beta cmdlets.
$cmdletsToBeExported = @("Get-GcLogEntry", "New-GcLogEntry", "New-GcLogMonitoredResource",
                         "Get-GcLog", "Remove-GcLog", "New-GcLogSink", "Get-GcLogSink",
                         "Update-GcLogSink", "Remove-GcLogSink", "Get-GcpsTopic",
                         "New-GcpsTopic", "Remove-GcpsTopic", "New-GcpsSubscription",
                         "Get-GcpsSubscription", "Set-GcpsSubscriptionConfig",
                         "Remove-GcpsSubscription", "New-GcpsMessage", "Publish-GcpsMessage",
                         "Get-GcpsMessage", "Set-GcpsAckDeadline", "Send-GcpsAck"
                         "Get-GcIamPolicyBinding", "Add-GcIamPolicyBinding",
                         "Get-BqDataset", "Set-BqDataset", "New-BqDataset", "Remove-BqDataset",
                         "Get-BqTable", "Set-BqTable", "New-BqTable", "Remove-BqTable",
                         "New-BqSchema", "Set-BqSchema", "Add-BqTableRows", "Get-BqTableRows",
                         "Get-BqJob", "Start-BqJob", "Receive-BqJob", "Stop-BqJob",
                         "Get-GkeCluster", "New-GkeNodeConfig", "Add-GkeCluster",
                         "Remove-GkeCluster", "Add-GkeNodePool", "Get-GkeNodePool",
                         "New-GkeNodePool")
$cmdletsToBeExported

Add Set-GkeCluster to list of beta cmdlets

# List of beta cmdlets.
$cmdletsToBeExported = @("Get-GcLogEntry", "New-GcLogEntry", "New-GcLogMonitoredResource",
                         "Get-GcLog", "Remove-GcLog", "New-GcLogSink", "Get-GcLogSink",
                         "Update-GcLogSink", "Remove-GcLogSink", "Get-GcpsTopic",
                         "New-GcpsTopic", "Remove-GcpsTopic", "New-GcpsSubscription",
                         "Get-GcpsSubscription", "Set-GcpsSubscriptionConfig",
                         "Remove-GcpsSubscription", "New-GcpsMessage", "Publish-GcpsMessage",
                         "Get-GcpsMessage", "Set-GcpsAckDeadline", "Send-GcpsAck"
                         "Get-GcIamPolicyBinding", "Add-GcIamPolicyBinding",
                         "Get-BqDataset", "Set-BqDataset", "New-BqDataset", "Remove-BqDataset",
                         "Get-BqTable", "Set-BqTable", "New-BqTable", "Remove-BqTable",
                         "New-BqSchema", "Set-BqSchema", "Add-BqTableRows", "Get-BqTableRows",
                         "Get-BqJob", "Start-BqJob", "Receive-BqJob", "Stop-BqJob",
                         "Get-GkeCluster", "New-GkeNodeConfig", "Add-GkeCluster",
                         "Set-GkeCluster", "Remove-GkeCluster", "Add-GkeNodePool",
                         "Get-GkeNodePool", "New-GkeNodePool")
$cmdletsToBeExported


# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

dotnet restore --force
dotnet test --no-restore --test-adapter-path:. --logger:junit 2>&1 | %{ "$_" }

Increase the overall timeout for the full test run. - If several instances of tests are running in parallel, the usage export bucket tests will need to retry some, and that will consume time.

# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import-module -DisableNameChecking ..\..\..\BuildTools.psm1

Set-TestTimeout 600

dotnet restore --force
dotnet test --no-restore --test-adapter-path:. --logger:junit 2>&1 | %{ "$_" }


param (
[string] $filePath,
[string] $major,
[string] $minor,
[string] $patch
)

# Get the task.json as a powershell object
$task = Get-Content -Raw -Path $filePath | ConvertFrom-Json

$task.version.Major = $major
$task.version.Minor = $minor
$task.version.Patch = $patch

# get this as a string again

ConvertTo-Json $task | Set-Content -Path $filePath

Make sure to convert the whole object back to the JSON file

param (
[string] $filePath,
[string] $major,
[string] $minor,
[string] $patch
)

# Get the task.json as a powershell object
$task = Get-Content -Raw -Path $filePath | ConvertFrom-Json

$task.version.Major = $major
$task.version.Minor = $minor
$task.version.Patch = $patch

# get this as a string again

ConvertTo-Json $task -Depth 999 | Set-Content -Path $filePath


## This configuration file uses BoxStarter to configure the system
## and Chocolatey to install necessary packages

Write-Output "Starting Common Configuration and Installs"

choco feature enable --name=allowGlobalConfirmation

## System Configuration

# Set-ExplorerOptions -showFileExtensions

Write-Output "Enabling Remote Desktop"

Enable-RemoteDesktop
Set-NetFirewallRule -Name RemoteDesktop-UserMode-In-TCP -Enabled True

Disable-InternetExplorerESC # Turns off Internet Explorer Enhanced Security Configuration that is on by default on Server OS versions.

Disable-BingSearch # Disables the Bing Internet Search when searching from the search field in the taskbar or Start Menu

Write-Host "Hiding Taskbar Search box / button..."
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" -Name "SearchboxTaskbarMode" -Type DWord -Value 0

Write-Host "Hiding Task View button..."
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ShowTaskViewButton" -Type DWord -Value 0

Write-Output "Enabling and Running Windows Update"

Enable-MicrosoftUpdate

Write-Output "Beginning Chocolatey installs"

## Web Browsers

choco install GoogleChrome
choco install Firefox

## Common System Tools

choco install 7zip.install
choco install vscode

# choco install rdcman

# choco install google-backup-and-sync

choco install adobereader

choco install greenshot

Add f.lux because it was killing my eyes

## This configuration file uses BoxStarter to configure the system
## and Chocolatey to install necessary packages

Write-Output "Starting Common Configuration and Installs"

choco feature enable --name=allowGlobalConfirmation

## System Configuration

# Set-ExplorerOptions -showFileExtensions

Write-Output "Enabling Remote Desktop"

Enable-RemoteDesktop
Set-NetFirewallRule -Name RemoteDesktop-UserMode-In-TCP -Enabled True

Disable-InternetExplorerESC # Turns off Internet Explorer Enhanced Security Configuration that is on by default on Server OS versions.

Disable-BingSearch # Disables the Bing Internet Search when searching from the search field in the taskbar or Start Menu

Write-Host "Hiding Taskbar Search box / button..."
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Search" -Name "SearchboxTaskbarMode" -Type DWord -Value 0

Write-Host "Hiding Task View button..."
Set-ItemProperty -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ShowTaskViewButton" -Type DWord -Value 0

Write-Output "Enabling and Running Windows Update"

Enable-MicrosoftUpdate

Write-Output "Beginning Chocolatey installs"

## Web Browsers

choco install GoogleChrome
choco install Firefox

## Common System Tools

choco install 7zip.install
choco install vscode

# choco install rdcman

# choco install google-backup-and-sync

choco install adobereader

choco install greenshot

choco install f.lux


param (
    [string]$path_to_packages = "c:\d2iq\dcos\packages",
    [string]$path_to_dcos_bin = "c:\d2iq\dcos\bin",
    [string]$path_to_dcos_conf = "c:\d2iq\dcos\etc\mesos"
    )

$domain = & $path_to_dcos_bin\fault-domain-detect-win.ps1
Set-Content $path_to_dcos_conf\domain.json $domain -Force

$packagebootsrapname = [string[]](Get-ChildItem $path_to_packages -Recurse -Filter bootstrap--*)
$pathtobootstrap = "$path_to_packages\$packagebootsrapname"

$Env:PYTHONPATH = "$pathtobootstrap\lib\python36\site-packages;$pathtobootstrap"

& python "$pathtobootstrap\bin\bootstrap" dcos-mesos-slave

Call bootstrap.ps1 when installing Mesos on Windows

param (
    [string]$path_to_dcos_bin = "c:\d2iq\dcos\bin",
    [string]$path_to_dcos_conf = "c:\d2iq\dcos\etc\mesos"
    )

$domain = & $path_to_dcos_bin\fault-domain-detect-win.ps1
Set-Content $path_to_dcos_conf\domain.json $domain -Force

& $path_to_dcos_bin\bootstrap.ps1 dcos-mesos-slave


Describe "Remove-Module" {
    $moduleName = "Microsoft.PowerShell.Platform"

    BeforeEach {
        Import-Module -Name $moduleName -Force
        (Get-Module -Name $moduleName).Name | Should be $moduleName
    }

    It "should be able to remove a module with using Name switch" {
        { Remove-Module -Name $moduleName } | Should Not Throw
        (Get-Module -Name $moduleName).Name | Should BeNullOrEmpty
    }

    It "should be able to remove a module with using ModuleInfo switch" {
        $a = Get-Module -Name $moduleName
        { Remove-Module -ModuleInfo $a } | Should Not Throw
        (Get-Module -Name $moduleName).Name | Should BeNullOrEmpty
    }

	AfterEach {
        Import-Module -Name $moduleName -Force
    }
}


Test for invoke-dbacycelerrorlog Locally this test fails will see if Appveyor gets same result

$CommandName = $MyInvocation.MyCommand.Name.Replace(".ps1", "")
Write-Host -Object "Running $PSCommandPath" -ForegroundColor Cyan
. "$PSScriptRoot\constants.ps1"
Describe "Invoke-DbaCycleErrorLog Unit Tests" -Tag "UnitTests" {
	Context "Validate parameters" {
		$paramCount = 4
		$defaultParamCount = 13
		[object[]]$params = (Get-ChildItem function:\Invoke-DbaCycleErrorLog).Parameters.Keys
		$knownParameters = 'SqlInstance', 'SqlCredential', 'Type', 'Silent'
		it "Should contian our parameters" {
			( (Compare-Object -ReferenceObject $knownParameters -DifferenceObject $params -IncludeEqual | Where-Object SideIndicator -eq "==").Count ) | Should Be $paramCount
		}
		it "Should only contain our parameters" {
			$params.Count - $defaultParamCount | Should Be $paramCount
		}
	}
}
Describe "Invoke-DbaCycleErrorLog Integration Test" -Tag "IntegrationTests" {
	$results = Invoke-DbaCycleErrorLog -SqlInstance sql2008 -Type instance

	Context "Validate output" {
		it "Should have correct properties" {
			$ExpectedProps = 'ComputerName,InstanceName,SqlInstance,LogType,IsSuccessful,Notes'.Split(',')
			($results.PsObject.Properties.Name | Sort-Object) | Should Be ($ExpectedProps | Sort-Object)
		}
		it "Should cycle instance error log" {
			$results.LogType | Should Be "instance"
		}
	}
}


. .\System\Invoke-Pipeline.ps1

# Invokes a "Cascade" of pipelines. All pipelines contained in $pipelinePath are executed in order
# Then, after each root pipeline exists, all pipelines of the same name in any of the cascade paths are also executed (eg 'extending' the base pipeline)
# Finally, any pipelines in the cascade paths that are NOT present in $pipelinePath are executed (eg 'custom' pipelines)
function Invoke-Pipeline-Cascade([string]$pipelinePath, [string[]]$cascadePaths) {
    # get all pipelines in primary
    $pipelines = Get-ChildItem $pipelinePath -Directory

    # execute pipelines in order, and if pipeline exists in any cascades execute that immediately afterwards
    foreach($pipeline in $pipelines) {
        Invoke-Pipeline $pipeline.FullName

        foreach($cascade in $cascadePaths) {
            $cascadePath = Join-Path $cascade $pipeline.Name
            if(Test-Path $cascadePath) {
                Invoke-Pipeline $cascadePath
            }
        }
    }

    # now we execute any custom pipelines in the cascades that are NOT defined in the primary
    foreach($cascade in $cascadePaths)
    {
        $cascadePipelines = Get-ChildItem $cascade -Directory
        foreach($cascadePipeline in $cascadePipelines) {
            $primaryPath = Join-Path $pipelinePath $cascadePipeline.Name

            if(!(Test-Path $primaryPath)) {
               Invoke-Pipeline $cascadePipeline.FullName
            }
        }
    }
}

Fix bug if cascade root path didn't exist

. .\System\Invoke-Pipeline.ps1

# Invokes a "Cascade" of pipelines. All pipelines contained in $pipelinePath are executed in order
# Then, after each root pipeline exists, all pipelines of the same name in any of the cascade paths are also executed (eg 'extending' the base pipeline)
# Finally, any pipelines in the cascade paths that are NOT present in $pipelinePath are executed (eg 'custom' pipelines)
function Invoke-Pipeline-Cascade([string]$pipelinePath, [string[]]$cascadePaths) {
    # get all pipelines in primary
    $pipelines = Get-ChildItem $pipelinePath -Directory

    # execute pipelines in order, and if pipeline exists in any cascades execute that immediately afterwards
    foreach($pipeline in $pipelines) {
        Invoke-Pipeline $pipeline.FullName

        foreach($cascade in $cascadePaths) {
            $cascadePath = Join-Path $cascade $pipeline.Name
            if(Test-Path $cascadePath) {
                Invoke-Pipeline $cascadePath
            }
        }
    }

    # now we execute any custom pipelines in the cascades that are NOT defined in the primary
    foreach($cascade in $cascadePaths)
    {
        $cascadePipelines = Get-ChildItem $cascade -Directory -ErrorAction SilentlyContinue

        if($? -eq $true) {
            foreach($cascadePipeline in $cascadePipelines) {
                $primaryPath = Join-Path $pipelinePath $cascadePipeline.Name

                if(!(Test-Path $primaryPath)) {
                   Invoke-Pipeline $cascadePipeline.FullName
                }
            }
        }
    }
}


$ErrorActionPreference = "Stop"

$VersionOutput = $(cargo run --release --target=x86_64-pc-windows-msvc -- -V)
Copy-Item ..\..\target\x86_64-pc-windows-msvc\release\indentex.exe .

if (!($VersionOutput -match "indentex (\S+)")) {
    Throw "Could not parse indentex version"
}
$PackageVersion = $Matches[1]

(Get-Content .\indentex_template.wxs) `
    -replace '{{{version}}}', "$PackageVersion" `
    | Set-Content .\indentex.wxs

pandoc -f markdown -t rtf ..\..\LICENSE.md -s -o LICENSE.rtf

$TargetFile = "indentex_${PackageVersion}_amd64.msi"

& "$env:WIX\bin\candle" indentex.wxs
& "$env:WIX\bin\light" indentex.wixobj -ext WixUIExtension -sice:ICE91 -o $TargetFile

$FileHash = (Get-FileHash $TargetFile -Algorithm SHA512).Hash.ToLower()
Set-Content ".\$TargetFile.DIGEST" "$FileHash  $TargetFile"

Remove carriage return from digest file

$ErrorActionPreference = "Stop"

$VersionOutput = $(cargo run --release --target=x86_64-pc-windows-msvc -- -V)
Copy-Item ..\..\target\x86_64-pc-windows-msvc\release\indentex.exe .

if (!($VersionOutput -match "indentex (\S+)")) {
    Throw "Could not parse indentex version"
}
$PackageVersion = $Matches[1]

(Get-Content .\indentex_template.wxs) `
    -replace '{{{version}}}', "$PackageVersion" `
    | Set-Content .\indentex.wxs

pandoc -f markdown -t rtf ..\..\LICENSE.md -s -o LICENSE.rtf

$TargetFile = "indentex_${PackageVersion}_amd64.msi"

& "$env:WIX\bin\candle" indentex.wxs
& "$env:WIX\bin\light" indentex.wixobj -ext WixUIExtension -sice:ICE91 -o $TargetFile

$FileHash = (Get-FileHash $TargetFile -Algorithm SHA512).Hash.ToLower()
Set-Content -Path ".\$TargetFile.DIGEST" -Value "$FileHash  $TargetFile`n" -NoNewline


# Extract the ZIP if not already extracted
$BackupPath = Join-Path $PSScriptRoot "..\enron.zip"
$Destination = Join-Path $PSScriptRoot "..\_enron"

if ((Test-Path $BackupPath) -eq $false)
{
    throw "$BackupPath was not found."
}

if ((Test-Path $Destination) -eq $false)
{
    Write-Host "Extracting '$BackupPath' to '$Destination'..."
    Add-Type -Assembly "System.IO.Compression.FileSystem"
    [IO.Compression.ZipFile]::ExtractToDirectory($BackupPath, $Destination)
}

$cmd = 'db.dropDatabase()'

$cmd | mongo enron
mongorestore (Join-Path $Destination "dump")

$cmd = 'use enron
db.messages.count();'

$cmd | mongo


Enable-PSRemoting -Force
winrm quickconfig -q
winrm quickconfig -transport:http
winrm set winrm/config '@{MaxTimeoutms="1800000"}'
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="800"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/client/auth '@{Basic="true"}'
winrm set winrm/config/listener?Address=*+Transport=HTTP '@{Port="5985"}'
netsh advfirewall firewall set rule group="Windows Remote Administration" new enable=yes
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=allow
Set-Service winrm -startuptype "auto"
Restart-Service winrm

Set network connection type to private.

$NetworkListManager = [Activator]::CreateInstance([Type]::GetTypeFromCLSID([Guid]"{DCB00C01-570F-4A9B-8D69-199FDBA5723B}"))
$Connections = $NetworkListManager.GetNetworkConnections()
$Connections | ForEach-Object { $_.GetNetwork().SetCategory(1) }

Enable-PSRemoting -Force
winrm quickconfig -q
winrm quickconfig -transport:http
winrm set winrm/config '@{MaxTimeoutms="1800000"}'
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="800"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/client/auth '@{Basic="true"}'
winrm set winrm/config/listener?Address=*+Transport=HTTP '@{Port="5985"}'
netsh advfirewall firewall set rule group="Windows Remote Administration" new enable=yes
netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=allow
Set-Service winrm -startuptype "auto"
Restart-Service winrm


if ($DotFilesShowScriptEntry) {
    Write-Verbose -Message (Get-DotFilesMessage -Message $PSCommandPath)
}

if (!(Test-IsWindows)) {
    return
}

try {
    if (!$DotFilesFastLoad) {
        Test-ModuleAvailable -Name PSWinVitals
    }
} catch {
    Write-Verbose -Message (Get-DotFilesMessage -Message 'Skipping PSWinVitals settings as module not found.')
    return
}

Write-Verbose -Message (Get-DotFilesMessage -Message 'Loading PSWinVitals settings ...')

# Invoke-VitalMaintenance: Exclude Silverlight updates
$PSDefaultParameterValues['Invoke-VitalMaintenance:WUTitleExclude'] = 'Silverlight'

Update default parameters for PSWinVitals v0.5.0

if ($DotFilesShowScriptEntry) {
    Write-Verbose -Message (Get-DotFilesMessage -Message $PSCommandPath)
}

if (!(Test-IsWindows)) {
    return
}

try {
    if (!$DotFilesFastLoad) {
        Test-ModuleAvailable -Name PSWinVitals
    }
} catch {
    Write-Verbose -Message (Get-DotFilesMessage -Message 'Skipping PSWinVitals settings as module not found.')
    return
}

Write-Verbose -Message (Get-DotFilesMessage -Message 'Loading PSWinVitals settings ...')

# Get-VitalInformation: Exclude Silverlight updates
$PSDefaultParameterValues['Get-VitalInformation:WUParameters'] = @{ NotTitle = 'Silverlight' }

# Invoke-VitalMaintenance: Exclude Silverlight updates
$PSDefaultParameterValues['Invoke-VitalMaintenance:WUParameters'] = @{ NotTitle = 'Silverlight' }


Create script to build Windows solutions

## Parameters
#   platform: WindowsStore | WindowsPhone | WindowsUniversal
#   projectPath: in relation to the script path
#   outputPath: in relation to the project path
#   unityPath: absolute path to Unity.exe

[string]$platform=$args[0]
[string]$projectPath="$PSScriptRoot\"+$args[1]
[string]$outputPath=$args[2]
[string]$unityPath=$args[3]

if(Test-Path $projectPath\logs)
{
 rmdir $projectPath\logs -Force -Recurse | Out-Null
}
mkdir $projectPath\logs | Out-Null

Try
{

if(!(Test-Path "$unityPath"))
{
   throw "Unity executable was not found at $unityPath"
}

$methodName = "Assets.Editor.MarkerMetro.MarkerMetroBuilder."

Switch ($platform)
{
	"WindowsStore"
	{
		$methodName += "BuildMetro"
		$displayName = "Windows Store"
		$buildTarget = "Metro"
	}

	"WindowsPhone"
	{
		$methodName += "BuildWP8"
		$displayName = "Windows Phone"
		$buildTarget = "WP8"
	}

	"WindowsUniversal"
	{
		$methodName += "BuildUniversal"
		$displayName = "Windows Universal 8.1"
		$buildTarget = "Metro"
	}
}

& "$unityPath" -buildTarget $buildTarget -projectPath $projectPath -batchmode -quit -logFile $projectPath\logs\$methodName.log -executeMethod $methodName -CustomArgs:outputPath=$outputPath | Out-Null

$result = $?

Get-Content $projectPath\logs\$methodName.log | Out-Default

if(!((Get-Content $projectPath\logs\$methodName.log -Tail 10).Contains("Exiting batchmode successfully now!"))){
	throw "Batch Mode did not complete successfully"
}

if(!$result){
  Write-Host "##teamcity[message text='$displayName Player build failed' errorDetails='The process exited with a non-zero exit code. Check the logs for details' status='FAILURE']"
}

if(!$result){
  throw "$displayName Player Build Failed"
}
}
Finally {
Write-Host "##teamcity[blockClosed name='Building $displayName Player Build']"
}


Add script for enabling autocomplete in PowerShell v3

$Completion_clc = {

    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)

    (invoke-expression "$parameterName --generate-bash-completion").Split(" ") |
    ForEach-Object {
        New-Object System.Management.Automation.CompletionResult $_, $_, 'ParameterValue', ('{0} ({1})' -f $_, $_)
    }
}

# Register the handler.
if (-not $global:options) {
    $global:options = @{CustomArgumentCompleters = @{};NativeArgumentCompleters = @{}}
}
$global:options['NativeArgumentCompleters']['clc.exe'] = $Completion_clc

# Override tabexpansion2.
$function:tabexpansion2 = $function:tabexpansion2 -replace
    'End\r\n{',
    'End { if ($null -ne $options) { $options += $global:options} else {$options = $global:options}'


# Default to UTF-8 encoding with Out-File
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'

# Our custom prompt with various integrations
Function Prompt {
    $prompt = ''

    # posh-git
    if ($GitPromptScriptBlock) {
        $prompt += & $GitPromptScriptBlock
    }

    # Default
    if (-not $prompt) {
        $prompt = 'PS {0}{1} ' -f $ExecutionContext.SessionState.Path.CurrentLocation, '>' * ($NestedPromptLevel + 1)
    }

    # ConEmu
    if ($ConEmuPrompt) {
        $prompt += & $ConEmuPrompt
    }

    return $prompt
}

Increase the default number of array elements to enumerate in PoSh

# Default to UTF-8 encoding with Out-File
$PSDefaultParameterValues['Out-File:Encoding'] = 'utf8'

# Number of elements to enumerate when displaying arrays
$FormatEnumerationLimit = 5

# Our custom prompt with various integrations
Function Prompt {
    $prompt = ''

    # posh-git
    if ($GitPromptScriptBlock) {
        $prompt += & $GitPromptScriptBlock
    }

    # Default
    if (-not $prompt) {
        $prompt = 'PS {0}{1} ' -f $ExecutionContext.SessionState.Path.CurrentLocation, '>' * ($NestedPromptLevel + 1)
    }

    # ConEmu
    if ($ConEmuPrompt) {
        $prompt += & $ConEmuPrompt
    }

    return $prompt
}


function Set-Project-Properties($version) {
    write-host "$version"

    set-regenerated-file "$pwd/Directory.Build.props" @"
<Project>
    <PropertyGroup>
        <Version>$version</Version>
        <Copyright>$(get-copyright)</Copyright>
    </PropertyGroup>
</Project>
"@
}

function Get-Copyright {
    $date = Get-Date
    $year = $date.Year
    $copyrightSpan = if ($year -eq $yearInitiated) { $year } else { "$yearInitiated-$year" }
    return " $copyrightSpan $owner"
}

function Set-Regenerated-File($path, $newContent) {
    if (-not (test-path $path -PathType Leaf)) {
        $oldContent = $null
    } else {
        $oldContent = [IO.File]::ReadAllText($path)
    }

    if ($newContent -ne $oldContent) {
        write-host "Generating $path"
        [System.IO.File]::WriteAllText($path, $newContent, [System.Text.Encoding]::UTF8)
    }
}

function Remove-Directory-Silently($path) {
    if (test-path $path) {
        write-host "Deleting $path"
        Remove-Item $path -recurse -force -ErrorAction SilentlyContinue | out-null
    }
}

Replace with unicode copyright symbol.

function Set-Project-Properties($version) {
    write-host "$version"

    set-regenerated-file "$pwd/Directory.Build.props" @"
<Project>
    <PropertyGroup>
        <Version>$version</Version>
        <Copyright>$(get-copyright)</Copyright>
    </PropertyGroup>
</Project>
"@
}

function Get-Copyright {
    $date = Get-Date
    $year = $date.Year
    $copyrightSpan = if ($year -eq $yearInitiated) { $year } else { "$yearInitiated-$year" }
    return  [char]0x00A9 + " $copyrightSpan $owner"
}

function Set-Regenerated-File($path, $newContent) {
    if (-not (test-path $path -PathType Leaf)) {
        $oldContent = $null
    } else {
        $oldContent = [IO.File]::ReadAllText($path)
    }

    if ($newContent -ne $oldContent) {
        write-host "Generating $path"
        [System.IO.File]::WriteAllText($path, $newContent, [System.Text.Encoding]::UTF8)
    }
}

function Remove-Directory-Silently($path) {
    if (test-path $path) {
        write-host "Deleting $path"
        Remove-Item $path -recurse -force -ErrorAction SilentlyContinue | out-null
    }
}


$fullpath = (Get-Item -Path ".\" -Verbose).FullName
$cred = Get-Credential -Message "This service requires domain privledges."
New-Service -Name "SqlAlertService" -DisplayName "SqlAlertService" -Credential $cred -StartupType Automatic -BinaryPathName $fullpath\DataCollector.exe -Description "Runs SQL queries and sends an email if the results don't match the expected value."

Correct exe name in powershell installer.

$fullpath = (Get-Item -Path ".\" -Verbose).FullName
$cred = Get-Credential -Message "This service requires domain privledges."
New-Service -Name "SqlAlertService" -DisplayName "SqlAlertService" -Credential $cred -StartupType Automatic -BinaryPathName $fullpath\SqlAlertService.exe -Description "Runs SQL queries and sends an email if the results don't match the expected value."


param([String]$key)

$span = New-TimeSpan -Start 2010/1/1 -End (Get-Date)
$version = "beta-" + $span.Days.ToString() + ($span.Hours * 60 + $span.Minutes).ToString("0000")
& dotnet restore
cd .\src\Folke.Identity.Elm
& dotnet pack --version-suffix $version
$file = Get-Item "bin\Debug\*-$version.nupkg"
nuget push $file.FullName $key
cd ..\..

Update source parameter for nuget

param([String]$key)

$span = New-TimeSpan -Start 2010/1/1 -End (Get-Date)
$version = "beta-" + $span.Days.ToString() + ($span.Hours * 60 + $span.Minutes).ToString("0000")
& dotnet restore
cd .\src\Folke.Identity.Elm
& dotnet pack --version-suffix $version
$file = Get-Item "bin\Debug\*-$version.nupkg"
nuget push $file.FullName $key -Source https://api.nuget.org/v3/index.json
cd ..\..


function Edit-ReplaceByFormat {
    param(
        [string] $fileToReplace,
        [string] $contentToReplace,
        [string] $replaceTo
    )

    Write-Output "Start replace content at source: '$fileToReplace'"
    Write-Output "Replace: '$contentToReplace' to the '$replaceTo'"

    if (!([System.IO.File]::Exists($fileToReplace)))
    {
        Write-Error "Error: File '$fileToReplace' does not exists"
        Exit
    }

    $reader = New-Object System.IO.StreamReader($fileToReplace)
    $content = $reader.ReadToEnd()

    $content = $content.Replace($contentToReplace, $replaceTo)
    $reader.Close()

    $projectFileStream = New-Object System.IO.StreamWriter($fileToReplace, $false)
    $projectFileStream.WriteLine($content)
    $projectFileStream.Close()
}

function Invoke-DownloadFile {
    param (
        [string] $fileUrl,
        [string] $outFile,
        [bool] $unzip,
        [string] $unzipFolder
    )

    Invoke-WebRequest -Uri "$fileUrl" -OutFile $outFile

    if (!(Test-Path -Path $outFile)) {
        Write-Error "Error: File '$paramValue' was not found"
        Exit
    }
}

function Invoke-ExtractFile {
    param (
        [string] $inputFile,
        [string] $outputPath
    )

    Add-Type -AssemblyName System.IO.Compression.FileSystem
    Write-Host "Extracting archive '$outFile' to the folder '$unzipFolder'"
    [System.IO.Compression.ZipFile]::ExtractToDirectory("$outFile", "$unzipFolder")
}

function Start-SonarAnalysis {
    param(
        [string] $projectKey,
        [string] $projectPath,
        [string] $version,
        [string] $solutionFile,
        [string] $toolsPath = (Get-Item -Path ".\" -Verbose).FullName,
        [string] $branch = "develop"
    )

    Write-Output "Start SonarQube analize for $solutionFile"
    $sonarMsbuildPath = Join-Path $toolsPath $Sonar_MsBuildToolExe
    & $sonarMsbuildPath begin /k:"$projectKey" /n:"$solutionFile" /v:"$version" /d:sonar.branch="$branch" /d:sonar.verbose=false
}

function Stop-SonarAnalysis {
    param (
        [string] $toolsPath = (Get-Item -Path ".\" -Verbose).FullName
    )

    Write-Output "End SonarQube analize"
    $sonarMsbuildPath = Join-Path $toolsPath $Sonar_MsBuildToolExe
    Write-Output "$sonarMsbuildPath"
	& $sonarMsbuildPath end > null
}


set-variable -name LastExitCode 0
set-strictmode -version 2.0
$ErrorActionPreference="Stop"

$CPCLocation="C:/CPC"

./build/scripts/cleanup_perf.ps1 $CPCLocation

if ( -not $? )
{
    echo "cleanup failed"
    exit 1
}

Invoke-WebRequest -Uri http://dotnetci.blob.core.windows.net/roslyn-perf/cpc.zip -OutFile cpc.zip
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null
[IO.Compression.ZipFile]::ExtractToDirectory('cpc.zip', $CPCLocation)

# Preview 4 specific
[Environment]::SetEnvironmentVariable("VS150COMNTOOLS", "C:\\Program Files (x86)\\Microsoft Visual Studio\\VS15Preview\\Common7\\Tools", "Process")

./cibuild.cmd /testPerfRun /release
if ($LASTEXITCODE -ne 0)
{
    exit $LASTEXITCODE
}

Remove Preview 4 specific hack

set-variable -name LastExitCode 0
set-strictmode -version 2.0
$ErrorActionPreference="Stop"

$CPCLocation="C:/CPC"

./build/scripts/cleanup_perf.ps1 $CPCLocation

if ( -not $? )
{
    echo "cleanup failed"
    exit 1
}

Invoke-WebRequest -Uri http://dotnetci.blob.core.windows.net/roslyn-perf/cpc.zip -OutFile cpc.zip
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null
[IO.Compression.ZipFile]::ExtractToDirectory('cpc.zip', $CPCLocation)

./cibuild.cmd /testPerfRun /release
if ($LASTEXITCODE -ne 0)
{
    exit $LASTEXITCODE
}


# Restore our NuGet packages
nuget sources Add -Name CitiesSkylines -Source $env:NUGET_CSL_URL -UserName $env:NUGET_CSL_USERNAME -Password $env:NUGET_CSL_PASSWORD -Verbosity quiet -NonInteractive
nuget restore .\appveyor\packages.config -SolutionDirectory .\ -NonInteractive

[xml]$packages = Get-Content .\appveyor\packages.config
$referencePath = ($packages.packages.package | % {(Get-Location).ToString() + "\packages\$($_.id).$($_.version)\lib\$($_.targetFramework)\"}) -Join ";"

# Do the actual build
msbuild /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /verbosity:minimal /p:ReferencePath="$referencePath"

# Copy the files we need to .\bin
if (Test-Path bin) {
    Remove-Item bin -recurse -force
}
mkdir bin | Out-Null;
Copy-Item "CSL Ambient Sounds Tuner\bin\$env:CONFIGURATION\*" -Destination bin -Recurse -Force -Exclude @("*.pdb")

# Copy the files we need to .\workshop
if (Test-Path workshop) {
    Remove-Item workshop -recurse -force
}
mkdir workshop | Out-Null;
mkdir workshop\Content | Out-Null;
Copy-Item PreviewImage.png -destination workshop
Copy-Item "bin/*" -destination workshop\Content -recurse

Fix build script to terminate on errors

# Restore our NuGet packages
nuget sources Add -Name CitiesSkylines -Source $env:NUGET_CSL_URL -UserName $env:NUGET_CSL_USERNAME -Password $env:NUGET_CSL_PASSWORD -Verbosity quiet -NonInteractive
if ($LASTEXITCODE -gt 0) { exit $LASTEXITCODE }
nuget restore .\appveyor\packages.config -SolutionDirectory .\ -NonInteractive
if ($LASTEXITCODE -gt 0) { exit $LASTEXITCODE }

[xml]$packages = Get-Content .\appveyor\packages.config
$referencePath = ($packages.packages.package | % {(Get-Location).ToString() + "\packages\$($_.id).$($_.version)\lib\$($_.targetFramework)\"}) -Join ";"

# Do the actual build
msbuild /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /verbosity:minimal /p:ReferencePath="$referencePath"
if ($LASTEXITCODE -gt 0) { exit $LASTEXITCODE }

# Copy the files we need to .\bin
if (Test-Path bin) {
    Remove-Item bin -recurse -force
}
mkdir bin | Out-Null;
Copy-Item "CSL Ambient Sounds Tuner\bin\$env:CONFIGURATION\*" -Destination bin -Recurse -Force -Exclude @("*.pdb")

# Copy the files we need to .\workshop
if (Test-Path workshop) {
    Remove-Item workshop -recurse -force
}
mkdir workshop | Out-Null;
mkdir workshop\Content | Out-Null;
Copy-Item PreviewImage.png -destination workshop
Copy-Item "bin/*" -destination workshop\Content -recurse


Add a file that contains helper functions for tests

Function Get-ExtentText
{
	Param(
	[Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic.CorrectionExtent] $violation,
	[string] $scriptPath
	)
	$scriptContent = Get-Content -Path $scriptPath
	$start = [System.Management.Automation.Language.ScriptPosition]::new($scriptPath, $violation.StartLineNumber, $violation.StartColumnNumber, $scriptContent[$violation.StartLineNumber - 1])
	$end = [System.Management.Automation.Language.ScriptPosition]::new($scriptPath, $violation.EndLineNumber, $violation.EndColumnNumber, $scriptContent[$violation.EndLineNumber - 1])
	$extent = [System.Management.Automation.Language.ScriptExtent]::new($start, $end)
	return($extent.Text)
}

Export-ModuleMember -Function Get-ExtentText


if([String]::IsNullOrEmpty($MyInvocation.PSScriptRoot)) {
    Write-Error 'This script should not be called directly! It has to be imported from a buckets test file!'
    exit 1
}

. "$psscriptroot\Scoop-TestLib.ps1"
. "$psscriptroot\..\lib\core.ps1"
. "$psscriptroot\..\lib\manifest.ps1"
. "$psscriptroot\..\lib\unix.ps1"

$repo_dir = (Get-Item $MyInvocation.PSScriptRoot).FullName

$repo_files = @(Get-ChildItem $repo_dir -file -recurse)

$project_file_exclusions = @(
    $([regex]::Escape($repo_dir)+'(\\|/).git(\\|/).*$'),
    '.sublime-workspace$',
    '.DS_Store$',
    'supporting(\\|/)validator(\\|/)packages(\\|/)*'
)

. "$psscriptroot\Import-File-Tests.ps1"
. "$psscriptroot\Scoop-Manifest.Tests.ps1"


# Dump info for https://github.com/xunit/xunit/issues/1345#issuecomment-335274948
 dir -r -fi *.deps.json | select FullName

$testProjects =  ( "LogJam.UnitTests", "LogJam.Internal.UnitTests", "LogJam.XUnit2.UnitTests" )
foreach ( $testProject in $testProjects) {
  pushd ".\test\$testProject"
  dotnet xunit -nobuild -internaldiagnostics $testProject.csproj
  popd
}

Add dump $env:Configuration for appveyor troubleshooting

# Dump info for https://github.com/xunit/xunit/issues/1345#issuecomment-335274948
 dir -r -fi *.deps.json | select FullName
"Configuration: $env:Configuration"
" "

$testProjects =  ( "LogJam.UnitTests", "LogJam.Internal.UnitTests", "LogJam.XUnit2.UnitTests" )
foreach ( $testProject in $testProjects) {
  pushd ".\test\$testProject"
  dotnet xunit -nobuild -internaldiagnostics $testProject.csproj
  popd
}


Describe "Export-FormatData" {

    Context "Check Export-FormatData can be called validly." {
	It "Should be able to be called without error" {
	    { Get-FormatData | Export-FormatData -Path "outputfile" } | Should Not Throw
	    Remove-Item "outputfile" -Force -ErrorAction SilentlyContinue
	}
    }

    Context "Check that the output is in the correct format" {
	It "Should not return an empty xml file" {
	    Get-FormatData | Export-FormatData -Path "outputfile"
	    $piped = Get-Content "outputfile"
	    $piped | Should Not Be ""
	    Remove-Item "outputfile" -Force -ErrorAction SilentlyContinue
	}

	It "Should have a valid xml tag at the start of the file" {
	    Get-FormatData | Export-FormatData -Path "outputfile"
	    $piped = Get-Content "outputfile"
	    $piped[0] | Should Be "<"
	    Remove-Item "outputfile" -Force -ErrorAction SilentlyContinue
	}
    }
}

Add Unit Test for Export-FormatData

Describe "Export-FormatData DRT Unit Tests" -Tags DRT{
    It "Test basic functionality" {
        $fd = Get-FormatData
        $tempFile = [io.path]::GetTempFileName()
        $results = Export-FormatData -InputObject $fd[0] -Path $tempFile
        $content = Get-Content $tempFile
        $formatViewDefinition = $fd[0].FormatViewDefinition
        $typeName = $fd[0].TypeName
        $content.Contains($typeName) | Should Be $true
        for ($i = 0; $i -lt $formatViewDefinition.Count;$i++)
        {
            $content.Contains($formatViewDefinition[$i].Name) | Should Be $true
        }
    }
}

Describe "Export-FormatData" {

    Context "Check Export-FormatData can be called validly." {
	It "Should be able to be called without error" {
	    { Get-FormatData | Export-FormatData -Path "outputfile" } | Should Not Throw
	    Remove-Item "outputfile" -Force -ErrorAction SilentlyContinue
	}
    }

    Context "Check that the output is in the correct format" {
	It "Should not return an empty xml file" {
	    Get-FormatData | Export-FormatData -Path "outputfile"
	    $piped = Get-Content "outputfile"
	    $piped | Should Not Be ""
	    Remove-Item "outputfile" -Force -ErrorAction SilentlyContinue
	}

	It "Should have a valid xml tag at the start of the file" {
	    Get-FormatData | Export-FormatData -Path "outputfile"
	    $piped = Get-Content "outputfile"
	    $piped[0] | Should Be "<"
	    Remove-Item "outputfile" -Force -ErrorAction SilentlyContinue
	}
    }
}


Add Join-XmlFiles and Add-VersionToNuspec script

function Join-XmlElements([System.Xml.XmlElement]$Template, [System.Xml.XmlElement]$Source, [System.Xml.XmlDocument]$TemplateDocument, [System.Xml.XmlDocument]$SourceDocument)
{
    $namespaceManager = New-Object System.Xml.XmlNamespaceManager $TemplateDocument.NameTable
    $namespaceManager.AddNamespace("nuspec", $Template.NamespaceURI)

    if (!$Template.HasChildNodes -and !$Source.HasChildNodes)
    {
        return;
    }
    elseif ($Template.FirstChild.LocalName -eq '#text')
    {
        $Source.FirstChild.Value = $Template.FirstChild.Value
        return;
    }

    foreach ($child in $Template.ChildNodes)
    {
        $xname = "nuspec:$($child.Name)"
        $matchingNode = $Source.SelectSingleNode($xname, $namespaceManager)

        if ($matchingNode -eq $null)
        {
            $copiedNode = $SourceDocument.ImportNode($child, $true)
            $Source.AppendChild($copiedNode)
        }
        else
        {
            Join-XmlElements $([System.Xml.XmlElement]$child) $([System.Xml.XmlElement]$matchingNode) $TemplateDocument $SourceDocument
        }
    }
}

function Join-XmlFiles([string]$Template, [string]$Source, [string]$Result)
{
    $templateDocument = [xml](Get-Content $Template)
    $sourceDocument = [xml](Get-Content $Source)

    $templateXmlElement = $templateDocument.DocumentElement
    $sourceXmlElement = $sourceDocument.DocumentElement

    Join-XmlElements $templateXmlElement $sourceXmlElement $templateDocument $sourceDocument

    $sourceDocument.Save($Result)
}

function Add-VersionToNuspec([string]$Source, [string]$Version)
{
    $xml = [xml](Get-Content $Source)

    $namespaceManager = New-Object System.Xml.XmlNamespaceManager $xml.NameTable
    $namespaceManager.AddNamespace("nuspec", $xml.DocumentElement.NamespaceURI)

    $node = $xml.DocumentElement.SelectSingleNode("descendant::nuspec:version", $namespaceManager)
    if ($node -eq $null)
    {
        return;
    }

    $formatted = "{0}-{1}" -f $node.FirstChild.Value, $Version
    $node.FirstChild.Value = $formatted

    $xml.Save($Source)
}


function FindInstalledApplication
{
  param($appName, $appVersion)

  if ((Get-WmiObject win32_operatingsystem).OSArchitecture -notmatch '64')
  {
      $keys= (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*')
  }
    else
  {
      $keys = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*','HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*')
  }

  if ($appVersion -eq $null) {
    @($keys | Where-Object {$_.DisplayName -like $appName -or $_.PSChildName -like $appName}).Length -gt 0
  }
  else{
    @($keys | Where-Object {$_.DisplayName -like $appName -or $_.PSChildName -like $appName  } | Where-Object {$_.DisplayVersion -eq $appVersion} ).Length -gt 0
  }

}

Check HKEY_CURRENT_USER in addition to HKEY_LOCAL_MACHINE

function FindInstalledApplication
{
  param($appName, $appVersion)

  if ((Get-WmiObject win32_operatingsystem).OSArchitecture -notmatch '64')
  {
    $keys= (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*')
    $possible_path= 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
    if (Test-Path $possible_path)
    {
      $keys+= (Get-ItemProperty $possible_path)
    }
  }
    else
  {
    $keys = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*','HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*')
    $possible_path= 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
    if (Test-Path $possible_path)
    {
      $keys+= (Get-ItemProperty $possible_path)
    }
    $possible_path= 'HKCU:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
    if (Test-Path $possible_path)
    {
      $keys+= (Get-ItemProperty $possible_path)
    }
  }

  if ($appVersion -eq $null) {
    @($keys | Where-Object {$_.DisplayName -like $appName -or $_.PSChildName -like $appName}).Length -gt 0
  }
  else{
    @($keys | Where-Object {$_.DisplayName -like $appName -or $_.PSChildName -like $appName  } | Where-Object {$_.DisplayVersion -eq $appVersion} ).Length -gt 0
  }

}


# =============================================================================
# Install the basic requirements for Windows software
# =============================================================================

# Url and path for each executable

$url_dx = "http://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe"
$path_dx = "C:\temp\directx.exe"

$url_net4 = "http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe"
$path_net4 = "C:\temp\dotNetFx40.exe"

$url_net45 = "http://download.microsoft.com/download/E/2/1/E21644B5-2DF2-47C2-91BD-63C560427900/NDP452-KB2901907-x86-x64-AllOS-ENU.exe"
$path_net45 = "C:\temp\dotNetFx45.exe"

$WebClient = New-Object System.Net.WebClient

# Download each file

$WebClient.DownloadFile($url_dx, $path_dx)
$WebClient.DownloadFile($url_net4, $path_net4)
$WebClient.DownloadFile($url_net45, $path_net45)

# Launch each installation in silent mode

Start-Process $path_dx "/q" -Wait
Start-Process $path_net4 "/q" -Wait
Start-Process $path_net45 "/q" -Wait


$installerName = "installer.exe"

Write-Host "Downloading .Net Core SDK"
Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?LinkID=809122" -OutFile $installerName

Write-Host "Installing .Net Core SDK"
Start-Process $installerName -ArgumentList "/quiet" -Wait

Write-Host ".Net Core installation finished"
Remove-Item $installerName

Stop .Net Core SDK installation on failure

$ErrorActionPreference = "Stop"
$installerName = "installer.exe"

Write-Host "Downloading .Net Core SDK"
Invoke-WebRequest -Uri "https://go.microsoft.com/fwlink/?LinkID=809122" -OutFile $installerName

Write-Host "Installing .Net Core SDK"
Start-Process $installerName -ArgumentList "/quiet" -Wait

Write-Host ".Net Core installation finished"
Remove-Item $installerName


# figure out the correct nuget package version (depends on whether this is a release or not)
$version = "$env:NUGET_RELEASE_VERSION"
if ("$env:APPVEYOR_REPO_TAG" -ne "true") # non-tagged (pre-release build)
{
	$version += "-unstable$env:APPVEYOR_BUILD_NUMBER"
}

# grab .nuspec file contents
$file = "$PSScriptRoot\..\$env:NUGET_FILE"
$contents = (Get-Content $file) | Out-String

# make sure there is exactly one occurance of <version>$version$</version> in the file
$pattern = '<version>\$version\$</version>'
$matches = [Regex]::Matches("$contents", "$pattern")
if ($matches.Count -ne 1)
{
	$count = $matches.Count
	Write-Error "<version>`$version`$</version> was found $count times in the nuspec file. If should have been found exactly once."
	Exit 1
}

# set the NUGET_VERSION env variable
[Environment]::SetEnvironmentVariable("NUGET_VERSION", "$version", "Process")
Write-Host "NUGET_VERSION set as $version"

Increment patch version on unstable builds.

# get current release version
$version = "$env:NUGET_RELEASE_VERSION"

# make sure version follows the 0.0.0 format
if (![Regex]::IsMatch($version, '^\d\.\d\.\d$'))
{
	Write-Error "Invalid NUGET_RELEASE_VERSION: $version"
	Exit 1
}

# set the correct nuget package version (depends on whether this is a release or not)
if ("$env:APPVEYOR_REPO_TAG" -ne "true") # non-tagged (pre-release build)
{
	# we want to increment the patch number for unstable builds
	$version = [Regex]::Replace($version, '^(\d\.\d\.)(\d)$', {
		param([System.Text.RegularExpressions.Match] $match)
		$val = [int]::Parse($match.Groups[2].Value)
		$val++
		$match.Groups[1].Value + $val
	})

	$version += "-unstable$env:APPVEYOR_BUILD_NUMBER"
}

# grab .nuspec file contents
$file = "$PSScriptRoot\..\$env:NUGET_FILE"
$contents = (Get-Content $file) | Out-String

# make sure there is exactly one occurance of <version>$version$</version> in the file
$pattern = '<version>\$version\$</version>'
$matches = [Regex]::Matches("$contents", "$pattern")
if ($matches.Count -ne 1)
{
	$count = $matches.Count
	Write-Error "<version>`$version`$</version> was found $count times in the nuspec file. If should have been found exactly once."
	Exit 1
}

# set the NUGET_VERSION env variable
[Environment]::SetEnvironmentVariable("NUGET_VERSION", "$version", "Process")
Write-Host "NUGET_VERSION set as $version"


Write-Output "---Creating Artifacts---"

# Build web application
Set-Location .\KenticoInspector.WebApplication
dotnet publish KenticoInspector.WebApplication.csproj /p:PublishDir=..\publish -c Release -r win-x64 --self-contained true

# Copy compiled front-end to publish folder
Set-Location .\ClientApp
mkdir "..\..\publish\dist"
Copy-Item ".\dist\*" -Recurse -Destination "..\..\publish\dist\"

# Go back to root
Set-Location ..\..\

# Create archive & push to Appveyor
$ filename = "Kentico Inspector $Env:SEMVER_VERSION.zip"
7z a $filename .\publish\*
appveyor PushArtifact $filename

Fix issue with using variable in 7z

Write-Output "---Creating Artifacts---"

# Build web application
Set-Location .\KenticoInspector.WebApplication
dotnet publish KenticoInspector.WebApplication.csproj /p:PublishDir=..\publish -c Release -r win-x64 --self-contained true

# Copy compiled front-end to publish folder
Set-Location .\ClientApp
mkdir "..\..\publish\dist"
Copy-Item ".\dist\*" -Recurse -Destination "..\..\publish\dist\"

# Go back to root
Set-Location ..\..\

# Create archive & push to Appveyor
7z a "Kentico Inspector $Env:SEMVER_VERSION.zip" .\publish\*
appveyor PushArtifact "Kentico Inspector $Env:SEMVER_VERSION.zip"


# Copyright(c) 2018 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

Import-Module -DisableNameChecking ..\..\..\BuildTools.psm1

$getBucketNameClause = 'Environment.GetEnvironmentVariable("AssetBucketName")'
BackupAndEdit-TextFile @("..\ExportAssets\ExportAssets.cs") @{
    "YOUR-GOOGLE-PROJECT-ID" = $env:GOOGLE_PROJECT_ID;
    "YOUR-BUCKET-NAME" = $getBucketNameClause
} {
        dotnet restore
	dotnet test --test-adapter-path:. --logger:junit
}

Replace the double quotes in the source code too.

# Copyright(c) 2018 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.

Import-Module -DisableNameChecking ..\..\..\BuildTools.psm1

$getBucketNameClause = 'Environment.GetEnvironmentVariable("AssetBucketName")'
BackupAndEdit-TextFile @("..\ExportAssets\ExportAssets.cs") @{
    "YOUR-GOOGLE-PROJECT-ID" = $env:GOOGLE_PROJECT_ID;
    '"YOUR-BUCKET-NAME"' = $getBucketNameClause
} {
    dotnet restore
	dotnet test --test-adapter-path:. --logger:junit
}


#Set-AdUserPwd -user "user" -oldpwd (ConvertTo-SecureString -AsPlainText "P@ssw0rd" -Force) -newpwd (ConvertTo-SecureString -AsPlainText "P@ssw0rd" -Force)

Function Set-AdUserPwd
{
    Param(
        [string]$user,
        [securestring]$oldpwd,
        [securestring]$newpwd
    ) #end param

    $user = (Get-ADUser $user).DistinguishedName
    Set-ADAccountPassword -Identity $user -NewPassword $newpwd -OldPassword $oldpwd -WhatIf
} # end function Set-AdUserPwd


$globalJson = Get-Content -Raw -Path global.json | ConvertFrom-Json
$version = $globalJson.Sdk.Version

Write-Host "##teamcity[setParameter name='DotnetCoreVersion' value='$version']"


if (Test-Path $PROFILE) {
    $file = Get-Item $PROFILE -Force -ea 0
    $symlink = $file.Attributes -band [IO.FileAttributes]::ReparsePoint
    if (-Not $symlink) {
        Remove-Item $PROFILE
        cmd /c mklink "$PROFILE" "$($args[0])"
    }
} else {
    $profilePath = Split-Path $PROFILE
    if (!(Test-Path -Path $profilePath)) {
        New-Item -ItemType directory -Path $profilePath | Out-Null
    }
    cmd /c mklink "$PROFILE" "$($args[0])"
}

. $PROFILE

iex (new-object net.webclient).downloadstring('https://get.scoop.sh')
scoop update
scoop install concfg curl wget 7zip
scoop update concfg curl wget 7zip
concfg import -n solarized-light small concfg\source-code-pro.json
concfg clean

Install-Module PSReadline

Use Invoke-Expression instead of iex

if (Test-Path $PROFILE) {
    $file = Get-Item $PROFILE -Force -ea 0
    $symlink = $file.Attributes -band [IO.FileAttributes]::ReparsePoint
    if (-Not $symlink) {
        Remove-Item $PROFILE
        cmd /c mklink "$PROFILE" "$($args[0])"
    }
} else {
    $profilePath = Split-Path $PROFILE
    if (!(Test-Path -Path $profilePath)) {
        New-Item -ItemType directory -Path $profilePath | Out-Null
    }
    cmd /c mklink "$PROFILE" "$($args[0])"
}

. $PROFILE

Invoke-Expression (new-object net.webclient).downloadstring('https://get.scoop.sh')
scoop update
scoop install concfg curl wget 7zip
scoop update concfg curl wget 7zip
concfg import -n solarized-light small concfg\source-code-pro.json
concfg clean

Install-Module PSReadline


param(
	$prereleaseVersion = (property prereleaseVersion "beta-1"),
	$ignoreNugetPushErrors = (property ignoreNugetPushErrors "exists in compilation with different binary hash") #SymbolSource duplicate package error
)

Include-PluginScripts

task . Clean, Version, Compile, Test, Pack, Push

Update SymbolSource duplicate package error

param(
	$prereleaseVersion = (property prereleaseVersion "beta-1"),
	$ignoreNugetPushErrors = (property ignoreNugetPushErrors "The underlying connection was closed: An unexpected error occurred on a receive.;exists in compilation with different binary hash") #SymbolSource duplicate package error
)

Include-PluginScripts

task . Clean, Version, Compile, Test, Pack, Push


# Restore our NuGet packages
nuget sources Add -Name CitiesSkylines -Source $env:NUGET_CSL_URL -UserName $env:NUGET_CSL_USERNAME -Password $env:NUGET_CSL_PASSWORD -Verbosity quiet -NonInteractive
nuget restore .\appveyor\packages.config -SolutionDirectory .\ -NonInteractive

[xml]$packages = Get-Content .\appveyor\packages.config
$referencePath = ($packages.packages.package | % {"..\packages\$($_.id).$($_.version)\lib\$($_.targetFramework)\"}) -Join ";"

# Do the actual build
msbuild /verbosity:minimal /p:ReferencePath="$referencePath"

# Copy the files we need to .\bin
if (Test-Path bin) {
    Remove-Item bin -recurse -force
}
mkdir bin | Out-Null;
Copy-Item "CSL Ambient Sounds Tuner\bin\$env:CONFIGURATION\*" -Destination bin -Recurse -Force -Exclude @("*.pdb")

# Copy the files we need to .\workshop
if (Test-Path workshop) {
    Remove-Item workshop -recurse -force
}
mkdir workshop | Out-Null;
mkdir workshop\Content | Out-Null;
Copy-Item PreviewImage.png -destination workshop
Copy-Item "bin/*" -destination workshop\Content -recurse

Fix package location in build script

# Restore our NuGet packages
nuget sources Add -Name CitiesSkylines -Source $env:NUGET_CSL_URL -UserName $env:NUGET_CSL_USERNAME -Password $env:NUGET_CSL_PASSWORD -Verbosity quiet -NonInteractive
nuget restore .\appveyor\packages.config -SolutionDirectory .\ -NonInteractive

[xml]$packages = Get-Content .\appveyor\packages.config
$referencePath = ($packages.packages.package | % {(Get-Location).ToString() + "\packages\$($_.id).$($_.version)\lib\$($_.targetFramework)\"}) -Join ";"

# Do the actual build
msbuild /verbosity:minimal /p:ReferencePath="$referencePath"

# Copy the files we need to .\bin
if (Test-Path bin) {
    Remove-Item bin -recurse -force
}
mkdir bin | Out-Null;
Copy-Item "CSL Ambient Sounds Tuner\bin\$env:CONFIGURATION\*" -Destination bin -Recurse -Force -Exclude @("*.pdb")

# Copy the files we need to .\workshop
if (Test-Path workshop) {
    Remove-Item workshop -recurse -force
}
mkdir workshop | Out-Null;
mkdir workshop\Content | Out-Null;
Copy-Item PreviewImage.png -destination workshop
Copy-Item "bin/*" -destination workshop\Content -recurse


Add script to get Android package name of a unity project

cat .\ProjectSettings\ProjectSettings.asset | sls Android: | select -First 1 | foreach { $_ -split ' ' } | select -Last 1


Add script for cleaning up dead (orphaned) containers

Import-Module WebAdministration

$sites = Get-ChildItem IIS:\Sites
$appPools = Get-ChildItem IIS:\AppPools

$sites |
	Where-Object { $_.Name -ne 'Containerizer' } |
	Remove-Website

$appPools |
	Where-Object { $_.Name -ne 'Containerizer' } |
	Remove-WebAppPool


Add Powershell script to update external ID from AD

# For all nodes in UpGuard, update the external id by pulling the LDAP DN from AD
# You will be prompted for credentials to query AD

param (
    [string]$ApiKey = '',
    [string]$SecretKey = '',
    [string]$Url = 'https://',
    [string]$DomainController = '',
    [switch]$Insecure,
    [switch]$DryRun
)

# Ignore SSL certificate if `-insecure` is used
if ($Insecure)
{
  add-type @"
  using System.Net;
  using System.Security.Cryptography.X509Certificates;
  public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
      ServicePoint srvPoint, X509Certificate certificate,
      WebRequest request, int certificateProblem) {
      return true;
    }
  }
"@
  [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls11 -bor [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::SSL3 -bor [System.Net.SecurityProtocolType]::TLS;

$creds = (Get-Credential)

$headers = @{'Authorization' = "Token token=""$($ApiKey)$($SecretKey)""";
                 'Accept' = 'application/json'; 'Content-Type' = 'application/json'}

$nodes = Invoke-WebRequest -Uri "https://$($Url)/api/v2/nodes.json?page=1&per_page=50000" -Headers $headers -Method "GET"

if ($nodes.StatusCode > 400)
{
  throw [System.Exception] "$($nodes.StatusCode.ToString()) $($nodes.StatusDescription)"
}
else
{
    $nodes = ConvertFrom-Json -InputObject $nodes

    ForEach ($node in $nodes)
    {
        # Need to perform an additional lookup to get detailed node information.
        $node_details = Invoke-WebRequest -Uri "https://$($Url)/api/v2/nodes/$($node.id).json -Headers $headers -Method "GET"
        $node_details = ConvertFrom-Json -InputObject $node_details

        $dn = Get-ADComputer -Identity "$($node_details.name)" -Credential $creds -Server $DomainController
        $external_id = "LDAP://$($dn.DistinguishedName)"

        if ($DryRun -eq $false)
        {
            "Updating node $($node_details.name) external id to $($external_id)"
            $body = @{"node" = @{"external_id" = $external_id}}
            $body = ConvertTo-Json -InputObject $body
            $response = Invoke-WebRequest -Uri "https://$($Url)/api/v2/nodes/$($node.id).json" -Body $body -Headers $headers -Method "PUT"
            if ($response.StatusCode > 400)
            {
                throw [System.Exception] "$($response.StatusCode.ToString()) $($response.StatusDescription)"
            }
        } else {
            "Would update node $($node_details.name) external id to $($external_id)"
        }
    }
}


$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
$testRootDirectory = Split-Path -Parent $directory

Import-Module PSScriptAnalyzer
Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1")

$ruleConfiguration = @{
    Enable = $true
    CheckHashtable = $true
    CheckDSCConfiguration = $true
}

$settings = @{
    IncludeRules = @("PSAlignAssignmentStatement")
    Rules = @{
        PSAlignAssignmentStatement = $ruleConfiguration
    }
}

Describe "AlignAssignmentStatement" {
    Context "Hashtable" {
        It "Should align assignment statements in a hashtable" {
            $def = @'
$hashtable = @{
    property1 = "value"
    anotherProperty = "another value"
}
'@

# Expected output should be the following
# $hashtable = @{
#     property1       = "value"
#     anotherProperty = "another value"
# }

            $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
            $violations.Count | Should Be 1
            Test-CorrectionExtentFromContent $def $violations 1 ' ' '       '
        }
    }
}

Add test to verify correction for negative whitespace

$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
$testRootDirectory = Split-Path -Parent $directory

Import-Module PSScriptAnalyzer
Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1")

$ruleConfiguration = @{
    Enable = $true
    CheckHashtable = $true
    CheckDSCConfiguration = $true
}

$settings = @{
    IncludeRules = @("PSAlignAssignmentStatement")
    Rules = @{
        PSAlignAssignmentStatement = $ruleConfiguration
    }
}

Describe "AlignAssignmentStatement" {
    Context "Hashtable" {
        It "Should align assignment statements in a hashtable when need to add whitespace" {
            $def = @'
$hashtable = @{
    property1 = "value"
    anotherProperty = "another value"
}
'@

# Expected output after correction should be the following
# $hashtable = @{
#     property1       = "value"
#     anotherProperty = "another value"
# }

            $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
            $violations.Count | Should Be 1
            Test-CorrectionExtentFromContent $def $violations 1 ' ' '       '
        }

            It "Should align assignment statements in a hashtable when need to remove whitespace" {
            $def = @'
$hashtable = @{
    property1              = "value"
    anotherProperty = "another value"
}
'@

# Expected output should be the following
# $hashtable = @{
#     property1       = "value"
#     anotherProperty = "another value"
# }

            $violations = Invoke-ScriptAnalyzer -ScriptDefinition $def -Settings $settings
            $violations.Count | Should Be 1
            Test-CorrectionExtentFromContent $def $violations 1 '              ' '       '
        }
}
}


$packageName = '{{PackageName}}'
$url = '{{DownloadUrl}}'
$checksum = '{{Checksum}}'
$checksumType = 'sha1'
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
$installFile = Join-Path $toolsDir "$($packageName).exe"

$chocTempDir = Join-Path $Env:Temp "chocolatey"
$tempDir = Join-Path $chocTempDir "$packageName"
if (![System.IO.Directory]::Exists($tempDir)) {[System.IO.Directory]::CreateDirectory($tempDir)}
$zipFile = Join-Path $tempDir "$($packageName).zip"

$referer = "http://launcher.nirsoft.net/download.html"
$wc = New-Object System.Net.WebClient
$wc.Headers.Add("Referer", $referer)
$wc.DownloadFile($url, $zipFile)

Get-ChecksumValid -File "$zipFile" `
                  -Checksum "$checksum" `
                  -ChecksumType "$checksumType"

Get-ChocolateyUnzip -FileFullPath "$zipFile" `
                    -Destination "$toolsDir" `
                    -PackageName "$packageName"

Set-Content -Path ("$installFile.gui") `
            -Value $null

Use native powershell way to create dir if it doesn't exist

$packageName = '{{PackageName}}'
$url = '{{DownloadUrl}}'
$checksum = '{{Checksum}}'
$checksumType = 'sha1'
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
$installFile = Join-Path $toolsDir "$($packageName).exe"

$chocTempDir = Join-Path $Env:Temp "chocolatey"
$tempDir = Join-Path $chocTempDir "$packageName"
mkdir -f $tempDir | out-null
$zipFile = Join-Path $tempDir "$($packageName).zip"

$referer = "http://launcher.nirsoft.net/download.html"
$wc = New-Object System.Net.WebClient
$wc.Headers.Add("Referer", $referer)
$wc.DownloadFile($url, $zipFile)

Get-ChecksumValid -File "$zipFile" `
                  -Checksum "$checksum" `
                  -ChecksumType "$checksumType"

Get-ChocolateyUnzip -FileFullPath "$zipFile" `
                    -Destination "$toolsDir" `
                    -PackageName "$packageName"

Set-Content -Path ("$installFile.gui") `
            -Value $null


Function Invoke-GitChildDir {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [String]$Command,

        [ValidateNotNullOrEmpty()]
        [String]$Path
    )

    $GitArgs = $Command.Split()

    if (!$Path) {
        $Path = Get-Location -PSProvider FileSystem
    }

    $OrigLocation = Get-Location
    Set-Location -Path $Path

    $Dirs = Get-ChildItem -Directory
    foreach ($Dir in $Dirs) {
        $GitDir = Join-Path -Path $Dir -ChildPath '.git'
        if (-not (Test-Path -Path $GitDir -PathType Container)) {
            Write-Verbose -Message ('Skipping directory: {0}' -f $Dir.Name)
            continue
        }

        Write-Host -ForegroundColor Green -Object ('Running in: {0}' -f $Dir.Name)
        Set-Location -Path $Dir
        & git @GitArgs
        Set-Location -Path $Path
        Write-Host
    }

    Set-Location -Path $OrigLocation
}

Add missing comment to Invoke-GitChildDir

# Invoke a Git command in all Git repositories
Function Invoke-GitChildDir {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory)]
        [String]$Command,

        [ValidateNotNullOrEmpty()]
        [String]$Path
    )

    $GitArgs = $Command.Split()

    if (!$Path) {
        $Path = Get-Location -PSProvider FileSystem
    }

    $OrigLocation = Get-Location
    Set-Location -Path $Path

    $Dirs = Get-ChildItem -Directory
    foreach ($Dir in $Dirs) {
        $GitDir = Join-Path -Path $Dir -ChildPath '.git'
        if (-not (Test-Path -Path $GitDir -PathType Container)) {
            Write-Verbose -Message ('Skipping directory: {0}' -f $Dir.Name)
            continue
        }

        Write-Host -ForegroundColor Green -Object ('Running in: {0}' -f $Dir.Name)
        Set-Location -Path $Dir
        & git @GitArgs
        Set-Location -Path $Path
        Write-Host
    }

    Set-Location -Path $OrigLocation
}


Write-Host "Ensconce - Powershell4Polyfill Loading"

function Clear-DnsClientCache()
{
	$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
	$ProcessInfo.FileName = "ipconfig.exe"
	$ProcessInfo.RedirectStandardError = $true
	$ProcessInfo.RedirectStandardOutput = $true
	$ProcessInfo.UseShellExecute = $false
	$ProcessInfo.Arguments = "/flushdns"

	$Process = New-Object System.Diagnostics.Process
	$Process.StartInfo = $ProcessInfo
	$Process.Start() | Out-Null
	$Process.WaitForExit()

	$output = $Process.StandardOutput.ReadToEnd()
	write-host $output
}

Write-Host "Ensconce - Powershell4Polyfill Loaded"

Add addtional logging to make it clear it's a polyfill

Write-Host "Ensconce - Powershell4Polyfill Loading"

function Clear-DnsClientCache()
{
	Write-Host "Calling IPConfig /flushdns to simulate Powershell 5 function"

	$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
	$ProcessInfo.FileName = "ipconfig.exe"
	$ProcessInfo.RedirectStandardError = $true
	$ProcessInfo.RedirectStandardOutput = $true
	$ProcessInfo.UseShellExecute = $false
	$ProcessInfo.Arguments = "/flushdns"

	$Process = New-Object System.Diagnostics.Process
	$Process.StartInfo = $ProcessInfo
	$Process.Start() | Out-Null
	$Process.WaitForExit()

	$output = $Process.StandardOutput.ReadToEnd()
	write-host $output
}

Write-Host "Ensconce - Powershell4Polyfill Loaded"