Push-Deployment.ps1

function Push-Deployment
{
    <#
    .Synopsis
        Pushes a deployment to Azure
    .Description
        Pushes an existing deployment to an Azure service
    .Example
        Push-Deployment "StartAutomating" ".\startautomating.cspkg" ".\startautomating.cscfg" -FirstLabel Start-Scripting -Second Update-Web
    .Link
        Get-Deployment
    .Link
        Import-Deployment
    .Link
        Remove-Deployment
    #>

    [CmdletBinding(DefaultParameterSetName='PushAzureDeployment')]
    [OutputType([Nullable])]
    param(
    # The name of the service
    [Parameter(Mandatory=$true,ParameterSetName='PushAzureDeployment',ValueFromPipelineByPropertyName=$true)]
    [string]
    $ServiceName,

    # The path to the CSPackage (.cspkg) file
    [Parameter(Mandatory=$true,ParameterSetName='PushAzureDeployment',ValueFromPipelineByPropertyName=$true)]
    [string]
    $PackagePath,

    # The path to the CSConfigurationFile (.cscfg) file
    [Parameter(Mandatory=$true,ParameterSetName='PushAzureDeployment',ValueFromPipelineByPropertyName=$true)]
    [string]
    $ConfigurationPath,

    # The label of the first deployment slot
    [Parameter(ParameterSetName='PushAzureDeployment',ValueFromPipelineByPropertyName=$true)]
    [string]
    $FirstLabel = "Primary",
    
    # The label of the second deployment slot
    [Parameter(ParameterSetName='PushAzureDeployment',ValueFromPipelineByPropertyName=$true)]
    [string]
    $SecondLabel = "Secondary",

    # The name of the storage account that will contain the bits
    [Parameter(Mandatory=$true,ParameterSetName='PushToAzureVMs')]
    [string]
    $StorageAccount,

    # The storage key of the storage account that will contain the bits
    [Parameter(Mandatory=$true,ParameterSetName='PushToAzureVMs')]
    [string]
    $StorageKey,

    # If set, will push the deployment to Azure VMs
    [Parameter(Mandatory=$true,ParameterSetName='PushToAzureVMs')]
    [Switch]
    $ToAzureVM,

    # The name of the computers that will receive the deployment
    [Parameter(ParameterSetName='PushToAzureVMs')]    
    [string[]]
    $ComputerName,

    
    # The name of the computers that will receive the deployment
    [Parameter(Mandatory=$true,ParameterSetName='PushToAzureVMs')]
    [Management.Automation.PSCredential]
    $Credential

    
    )

    process {
        if ($PSCmdlet.ParameterSetName -eq 'PushAzureDeployment') {
            #region Push a deployment package to Azure
            $azureModuleInstalled = Import-Module Azure -Global -PassThru
            if (-not $azureModuleInstalled) {
                Write-Error "Must install Azure module"
                return
            }
            $currentDeployment = Get-AzureDeployment -ServiceName $ServiceName

            $newlabel = if ($currentDeployment.label -ne $FirstLabel) {
                $FirstLabel
            } else {
                $SecondLabel
            }

            $resolvedPackagePath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($PackagePath)
            if (-not $resolvedPackagePath) { return } 
            $resolvedConfigPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($ConfigurationPath)
            if (-not $resolvedConfigPath) { return } 

            Remove-AzureDeployment -ServiceName $ServiceName -Slot Staging -Force -ErrorAction SilentlyContinue

            $deploymentParameters = @{
                Package=  "$resolvedPackagePath"
                Configuration =  "$resolvedConfigPath"
                Label = $newLabel
            }

        
            New-AzureDeployment @deploymentParameters -ServiceName $ServiceName -Slot Staging 
            #endregion Push a deployment package to Azure
        } elseif ($pscmdlet.ParameterSetName -eq 'PushToAzureVMs') {
            #region Push a deployment stored in blob storage into Azure VMs

            $params = @{} + $PSBoundParameters
$sb = {
    Add-Type -AssemblyName System.Web

}.ToString() + @"
function Expand-Zip {
    $((Get-Command Expand-Zip).Definition)
}
 
function Get-Web {
    $((Get-Command Get-Web).Definition)
}
 
function Import-Blob {
    $((Get-Command Import-Blob).Definition)
}
 
function Get-Blob {
    $((Get-Command Get-Blob).Definition)
}
"@



$sb = [ScriptBlock]::Create($sb)


$syncScript = "
`$null = New-module -Name Pipeworks -ScriptBlock {$sb}
`$storageAccount = '$storageAccount'
`$storageKey = '$storageKey'
"

$syncScript += {
# Move modules to old modules


Get-Blob -StorageAccount $StorageAccount -StorageKey $StorageKey | 
    Where-Object {$_.Container -like "*-source" } |
    ForEach-Object {
        
        $innerData = $_ | 
            Get-Blob | 
            Sort-Object { $_.LastModified } -Descending | 
            Select-Object -First 1 | 
            Get-Blob         
            
            
            
        $tempDir = [IO.Path]::GetTempPath()    
        $theFile = Join-Path $tempDir ($innerData.Container + $innerData.Name) 
        $theTempDir = Join-Path $tempDir $innerData.Container

        [IO.FILE]::WriteAllBytes("$theFile", $innerData.BlobData)


        

        Expand-Zip -ZipPath "$theFile" -OutputPath $theTempDir 

        $moduleDir = 
            dir $theTempDir -Recurse -Filter "$($innerData.Container.Replace("-source", '')).psm1" | 
            Split-Path | 
            Get-Item            

       

        if (-not $moduleDir) { return } 
        $destModuleDir = "$env:UserProfile\Documents\WindowsPowerShell\Modules\$($moduleDir.Name.Replace('-source', ''))"


        if (Test-Path $destModuleDir) {
            $destModuleDir | Remove-Item -Recurse -Force
        }        

        $null = New-Item -ItemType Directory -path $destModuleDir -ErrorAction SilentlyContinue

        
        
        $moduleName = $moduleDir | Split-Path -Leaf
            
        $dir = Get-Item $destModuleDir
        $filesExist = dir $moduleDir -Recurse -Force |
            Where-Object { -not $_.psIsContainer }
                
        if ($filesExist) {
            Move-Item "$env:UserProfile\Documents\WindowsPowerShell\Modules\$moduleName" "$env:UserProfile\Documents\WindowsPowerShell\Modules.Old.$((Get-Date).ToShortDateString().Replace('/','-'))" -ErrorAction SilentlyContinue  -Force

            $filesExist |
                ForEach-Object {
                    $_ | 
                        Copy-Item -Destination {                                                
                            $newPath = $_.FullName.Replace("$($moduleDir.Fullname)", "$($dir.FullName)")
                            
                            $newDir = $newPAth  |Split-Path
                            if (-not (Test-Path $newDir)) {
                                $null = New-Item -ItemType Directory -Path "$newDir" -Force
                            }
                            
                            
                            Write-Progress "Copying $($req.name)" "$newPath"
                            $newPath             
                            
                        } -Force
                }
        } 
                

            
        Remove-Item -LiteralPath $theTempDir -Force -Recurse

        
 
        






    } 


    
    #Move-Item "$home\Documents\WindowsPowerShell\SyncedModules" "$home\Documents\WindowsPowerShell\SyncedModules"

}

    
$syncScript = [ScriptBlock]::Create($syncScript)
Get-AzureVM |
    Where-Object {
        $comp = $_
        if ($params.ComputerName) {
            foreach ($cn in $ComputerName) {
                if ($comp.Name -like $cn) {
                    return $true 
                }
            }
        } else {
            return $true 
        }
    } |
    ForEach-Object {
        Invoke-Command -ComputerName "$($_.Name).cloudapp.net" -Credential $Credential -Authentication Credssp -ScriptBlock $syncScript -AsJob -JobName $_.Name
    }
            #endregion Push a deployment stored in blob storage into Azure VMs
        } elseif ($PSCmdlet.ParameterSetName -eq 'PushToLan') {
            



        }
        
        
    }
}