Skip to content

Instantly share code, notes, and snippets.

@MCKLMT
Last active August 29, 2015 14:16
Show Gist options
  • Save MCKLMT/04be9519c6eb1d3f6f77 to your computer and use it in GitHub Desktop.
Save MCKLMT/04be9519c6eb1d3f6f77 to your computer and use it in GitHub Desktop.
Create FTP on Azure with PowerShell in less than 9 minutes
Import-Module Azure # SDK 0.6.15
$executionTime = Measure-Command {
#region function InstallWinRMCert
function InstallWinRMCert($serviceName, $vmname)
{
$winRMCert = (Get-AzureVM -ServiceName $serviceName -Name $vmname | select -ExpandProperty vm).DefaultWinRMCertificateThumbprint
$AzureX509cert = Get-AzureCertificate -ServiceName $serviceName -Thumbprint $winRMCert -ThumbprintAlgorithm sha1
$certTempFile = [IO.Path]::GetTempFileName()
$AzureX509cert.Data | Out-File $certTempFile
# Target The Cert That Needs To Be Imported
$CertToImport = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 $certTempFile
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "LocalMachine"
$store.Certificates.Count
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)
$store.Add($CertToImport)
$store.Close()
Remove-Item $certTempFile
}
#endregion InstallWinRMCert
#region Configuration to edit before to run the script !!!
# Subcription to host the VM
$StorageAccountName = "myStorageAccount"
$SubscriptionName = "mySubscription"
# VM Config
$serviceName = 'test-ftp-4'
$vmName = 'test-ftp-4'
$vmLocation = "North Europe"
$instanceSize = "Large" # Supported values are "ExtraSmall", "Small", "Medium", "Large", "ExtraLarge", "A6", "A7".
# credentials
$adminUserName = "Osiatis"
$adminPassword = "MyVerySecureAndLongPassword"
# FTP Config
$startPort = 7000
$portCount = 15
$ftpWebSiteName = "Default FTP Site" #no special characters but you can add blank if you want
#Do not edit below this line
#endregion Configuration
#region Initialization
Set-AzureSubscription -SubscriptionName $SubscriptionName -CurrentStorageAccount $StorageAccountName
#endregion Initialization
# Get the last Windows Server 2012 Image
$VMImage = Get-AzureVMImage |`
Where-Object { $_.ImageFamily -eq "Windows Server 2012 Datacenter" } |`
Sort-Object PublishedDate -descending |`
Select-Object ImageName -First 1
# Create the configuration of the VM
$VM = New-AzureVMConfig -ImageName $VMImage.ImageName -InstanceSize $instanceSize -Name $vmName `
| Add-AzureProvisioningConfig -Windows -AdminUsername $adminUserName -Password $adminPassword -EnableWinRMHttp   
# Add ports for command and data
Add-AzureEndpoint -VM $VM -Name 'FTP-Command' -Protocol 'TCP' -LocalPort 21 -PublicPort 21
Add-AzureEndpoint -VM $VM -Name 'FTP-Data' -Protocol 'TCP' -LocalPort 20 -PublicPort 20
# Add ports for passive FTP
for ($i = 0; $i -lt $portCount; $i++)
{
$portName = [string]::Format("FTP-Passive-70{0}", $i.ToString("D2"))
$portNumber = ($startPort + $i)
Add-AzureEndpoint -VM $VM -Name $portName -Protocol 'TCP' -LocalPort $portNumber -PublicPort $portNumber  
}
Write-Host -ForegroundColor Green "Creating Virtual Machine..."
# Finally create the VM
New-AzureVM -VMs $VM -ServiceName $serviceName -Location $vmLocation -WaitForBoot
Write-Host -ForegroundColor Green "The Virtual Machine is up and running!"
# Import the certificate
InstallWinRMCert $serviceName $vmName
Write-Host -ForegroundColor Green "The certificate is installed!"
# Gets Uri and credentials to connect to the vm
$uri = Get-AzureWinRMUri -ServiceName $serviceName -Name $vmName
$credential = New-Object System.Management.Automation.PSCredential $adminUserName, (ConvertTo-SecureString $adminPassword -AsPlainText -Force)
#Get VIP of the VM
$externalIP = (Get-AzureVM -ServiceName $serviceName -Name $vmName | Get-AzureEndpoint | Select Vip -Last 1).Vip
# Invoke the command on the remote VM
Invoke-Command -ConnectionUri $uri.ToString() -Credential $credential -ArgumentList $startPort, $portCount, $applicationPoolName, $ftpWebSiteName, $externalIP -ScriptBlock {
# Parameters to send
param($startPort, $portCount, $applicationPoolName, $ftpWebSiteName, $externalIP)
Write-Host -ForegroundColor Green "Installing Windows Features..."
# Install the FTP and the IIS administration console
Add-WindowsFeature Web-Server, Web-WebServer, Web-Common-Http, Web-Static-Content, Web-Default-Doc, Web-Dir-Browsing, Web-Http-Errors, Web-Health, Web-Http-Logging, Web-Request-Monitor, Web-Security, Web-Filtering, Web-Stat-Compression, Web-Mgmt-Console, Web-Ftp-Server, Web-Ftp-Service, Web-Ftp-Ext
Write-Host -ForegroundColor Green "Configuration of the firewall..."  
# Configuration for the firewall
Get-NetFirewallRule | Where-Object { $_.DisplayName -like '*FTP*'} | Set-NetFirewallRule -Enabled True   
Set-NetFirewallSetting -EnableStatefulFtp True
Write-Host -ForegroundColor Green "Configuration of the IIS..."  
# Configure the port range for passive FTP
C:\Windows\System32\inetsrv\appcmd.exe set config /section:system.ftpServer/firewallSupport /lowDataChannelPort:$startPort /highDataChannelPort:$($startPort + $portCount -1)
# Configure the external IP
C:\Windows\System32\inetsrv\appcmd.exe set config /section:system.applicationHost/sites /siteDefaults.ftpServer.firewallSupport.externalIp4Address:$externalIP
# Add new FTPS Service
C:\Windows\System32\inetsrv\appcmd.exe set config -section:system.applicationHost/sites /siteDefaults.ftpServer.security.ssl.controlChannelPolicy:SslAllow /commit:apphost
C:\Windows\System32\inetsrv\appcmd.exe set config -section:system.applicationHost/sites /siteDefaults.ftpServer.security.ssl.dataChannelPolicy:SslAllow /commit:apphost
C:\Windows\System32\inetsrv\appcmd.exe set config -section:system.applicationHost/sites /siteDefaults.ftpServer.security.authentication.basicAuthentication.enabled:true
# Create the application pool name from the ftp site name. Can be edited but should be unique.
$applicationPoolName = $ftpWebSiteName.Replace(' ', '') + "AppPool"     
$rootFolder =  "C:\inetpub\ftproot\" + $ftpWebSiteName.Replace(' ', '')
#Create the root folder of the site
New-Item -ItemType Directory -Path $rootFolder
# Add new FTP Website
C:\Windows\System32\inetsrv\appcmd.exe add site /site.name:"$ftpWebSiteName" /bindings:ftp://*:21 /physicalpath:$rootFolder   
C:\Windows\System32\inetsrv\appcmd.exe add apppool /name:$applicationPoolName
C:\Windows\System32\inetsrv\appcmd.exe set app /app.name:"$ftpWebSiteName/" /applicationPool:$applicationPoolName
# Allow all users with a valid local account to connect and write files
C:\Windows\System32\inetsrv\appcmd.exe set config "$ftpWebSiteName" /section:system.ftpserver/security/authorization /+"[accessType='Allow',permissions='Read, Write',roles='',users='*']" /commit:apphost
# Restart the FTP Service
Restart-Service -Name 'ftpsvc'
Write-Host -ForegroundColor Green "Your FTP is up and running!"  
}
}
Write-Host -ForegroundColor Green -Object $executionTime
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment