Powershell script for SQL Azure back up to Microsoft Azure Blob - powershell

I want to take SQL Azure back up to Azure Blob storage using PowerShell. I have used the following script, but it is popping up for credential whenever I try to run.
I will be using this script from windows task scheduler, so how can I put user id and password inside PowerShell script so that it won't ask for username/password for subscription?
$subscriptionId = "xxxxxxxxxxxxxxxxxxxxx"
Login-AzureRmAccount
Set-AzureRmContext -SubscriptionId $subscriptionId
# Database to export
$DatabaseName = "xxxxxxxxxxx"
$ResourceGroupName = "xxxxxxxxxxx"
$ServerName = "xxxxxxxxxxxx"
$serverAdmin = "xxxxxxxxxxxxxxx"
$serverPassword = "xxxxxxxxxxx"
$securePassword = ConvertTo-SecureString -String $serverPassword -AsPlainText -Force
$creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $serverAdmin, $securePassword
# Generate a unique filename for the BACPAC
$bacpacFilename = $DatabaseName + (Get-Date).ToString("yyyyMMddHHmm") + ".bacpac"
# Storage account info for the BACPAC
$BaseStorageUri = "https://xxxxxxx.blob.core.windows.net/xxxxx/"
$BacpacUri = $BaseStorageUri + $bacpacFilename
$StorageKeytype = "StorageAccessKey"
$StorageKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$exportRequest = New-AzureRmSqlDatabaseExport -ResourceGroupName $ResourceGroupName -ServerName $ServerName `
-DatabaseName $DatabaseName -StorageKeytype $StorageKeytype -StorageKey $StorageKey -StorageUri $BacpacUri `
-AdministratorLogin $creds.UserName -AdministratorLoginPassword $creds.Password

You need to implement a non-interactive login in your script. Just modify your script as below:
##login Azure
$subscriptionId = "xxxxxxxxxxxxxxxxxxxxx"
$username = "<username>"
$password = "<password>"
$secstr = New-Object -TypeName System.Security.SecureString
$password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)}
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
Login-AzureRmAccount -Credential $cred
Select-AzureRmSubscription -SubscriptionId $subscriptionId
Note: you cannot login non-intereractively to Azure using a Microsoft Live account, such as *#hotmail.com, *#outlook.com.

There are probably two ways you can achieve this.
The first is to use the credential parameter as part of the Login-AzureRMAccount call. You can create a PSCredential in the powershell code and then use that. For example: Login-AzureRmAccount -Credential $credential
The second, and probably the safer/more secure way, is to create a service principal and then place the certificate on the machine in question. You can find instructions on how to do this here. After you have that created, you can use the Login-AzureRMAccount with the -ServicePrincipalparameter. See this link for more information.

Related

Connect-AzureAD PowerShell in Azure Function fails

Not related to Connect-azureAD powershell in azure function
I have a simple Azure function (HTTP trigger) written in PowerShell.
$user = 'user#domain.com';
$pass = 'password';
Import-Module AzureAD -UseWindowsPowerShell;
$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force;
$cred = New-Object System.Management.Automation.PSCredential ($Username, $secpasswd);
Connect-AzureAD -Credential $cred;
Disconnect-AzureAD;
Get-PSSession | Remove-PSSession;
The first time it runs, it works. If I hit it again, it throws an exception "Exception calling "GetSteppablePipeline" with "1" argument(s): "The parameter is incorrect." If I call it again after an hour, it works again (1 time), then it fails again with the same error.
Any ideas?
Thank you!
I have tested in my environment.
Please use the below code :
$user = 'user#domain.com';
$secpasswd = 'password' | ConvertTo-SecureString -AsPlainText -Force;
Import-Module AzureAD -UseWindowsPowerShell;
$cred = New-Object Management.Automation.PSCredential ($user, $secpasswd);
Connect-AzureAD -Credential $cred;
Disconnect-AzureAD;

"Start-Process : This command cannot be run due to the error: Access is denied." when specifying credentials?

Good morning :S.
I can enter into a PSSession and execute cmdlets just fine, however, as soon as I specify an account to use, it just throws back an access is denied error. I've even tested with the same account and password that established the PSSession. This works locally just fine.
I am trying to integrate this into an SCCM application, so there isn't a whole lot of wiggle room.
EDIT: I put an easier code that doesn't work either below:
$username = 'DOMAIN\Username'
$password = 'P#ssword'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process Notepad.exe -Credential $credential
#Execute variable
$myCommand = "'C:\Program Files (x86)\PGP Corporation\PGP Desktop\pgpwde' --status --disk 0"
#Credential Variables
$username = 'DOMAIN\USERNAME'
$Password = ConvertTo-SecureString -String 'P#ssword' -Force -AsPlainText
$credential = New-Object System.Management.Automation.PsCredential -ArgumentList $username, $Password
#Expression Variable
$expression = #"
try
{
& $myCommand | Out-File `C:\test.txt -Force
}
catch
{
`$_.Exception.Message | Out-File `C:\ERROR.txt -Force
}
"#
#Execute
Start-Process powershell.exe -ArgumentList "-c $expression" -Credential $credential

Powershell script in declarative jenkins pipeline

I am using environment credential to get the username and password. When I echo them they are printed perfectly as ****.
The next comes the powershell commands, when I run them separately, all the commands works perfectly. But through Jenkins pipeline it throws me the following error:
groovy.lang.MissingPropertyException: No such property: psw for class: groovy.lang.Binding
Can anyone explain is this correct way to incorporate powershell in Jenkins pipeline?
environment {
CREDENTIAL = credentials('Test')
}
stage('Deployment') {
steps {
echo "$CREDENTIAL_USR"
echo "$CREDENTIAL_PSW"
powershell """($psw = ConvertTo-SecureString -String $CREDENTIAL_PSW -AsPlainText -Force)"""
powershell """($mySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $CREDENTIAL_USR, $psw -Verbose)"""
powershell """(Set-Item WSMan:/localhost/Client/TrustedHosts -Value "*" -Force)"""
powershell """($session = New-PSSession -ComputerName "192.111.111.111" -Credential $mySecureCreds)"""
In case someone is here, and still trying to figure out what is the issue. I will share the solution that worked for me.
Use escaping before variable "$" sign in multi-line string.
powershell ("""
\$psw = ConvertTo-SecureString -String \$CREDENTIAL_PSW -AsPlainText -Force
\$mySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList \$CREDENTIAL_USR, \$psw -Verbose
Set-Item WSMan:/localhost/Client/TrustedHosts -Value "*" -Force
\$session = New-PSSession -ComputerName "192.111.111.111" -Credential \$mySecureCreds
""")
You can easily run multiline powershell commands in jenkins pipeline like this. Example, if you want to login to azure using service principal, you'll do something like below:
powershell '''
$pass = ConvertTo-SecureString your_client_secret -AsPlainText –Force
$cred = New-Object -TypeName pscredential –ArgumentList your_client_id, $pass
Login-AzureRmAccount -Credential $cred -ServicePrincipal –TenantId your_tenant_id
-vaultName "eusdevmbe2keyvault" -name "normalizedcontainername").SecretValueText
'''
Check here for reference https://jenkins.io/blog/2017/07/26/powershell-pipeline/
At the moment you're running each line in its own powershell process, so the results of the line before are not available to the next command.
I think you just need to move the script into a multi-line string:
powershell ("""
$psw = ConvertTo-SecureString -String $CREDENTIAL_PSW -AsPlainText -Force
$mySecureCreds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $CREDENTIAL_USR, $psw -Verbose
Set-Item WSMan:/localhost/Client/TrustedHosts -Value "*" -Force
$session = New-PSSession -ComputerName "192.111.111.111" -Credential $mySecureCreds
""")

Authenticate multiple Azure Powershell Functions

I have built a few Powershell functions using Azure Functions, and it is working like a charm.
Now that I have proven the concept I would very much like to refactor my existing functions.
First of all I would like to move the authentication required in my function to some kind of shared function or whatever.
Here is my example function, which return a list of all web apps in my resource group.
# Authenticate with subscription
$subscriptionId = "<SubscriptionId>"
$resourceGroupName = "<ResourceGroupName>";
$tenantId = "<TenantId>"
$applicationId = "<ApplicationId>"
$password = "<Password>"
$userPassword = ConvertTo-SecureString -String $password -AsPlainText -Force
$userCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $applicationId, $userPassword
Add-AzureRmAccount -TenantId $tenantid -ServicePrincipal -SubscriptionId $subscriptionId -Credential $userCredential
Get-AzureRmSubscription –SubscriptionId $subscriptionId | Select-AzureRmSubscription
# Get all web apps
$Websites = Get-AzureRmWebApp -ResourceGroupName $resourceGroupName
$Websites = $Websites | select name | ConvertTo-Json -Compress
# Write output
Out-File -Encoding Ascii -FilePath $res -inputObject $Websites
I would very much like to move everything from line 1 to line 10 somewhere else. Is it possible? If yes, can anyone please point me in the right direction here?
Update
Thanks to both Walter and Pragna I combined the two methods like this.
run.ps1
# Authenticate with subscription
Import-Module 'D:\home\site\wwwroot\bin\Authentication.ps1'
# Get all web apps
$Websites = Get-AzureRmWebApp -ResourceGroupName $env:ResourceGroupName
$Websites = $Websites | select name | ConvertTo-Json -Compress
# Write output
Out-File -Encoding Ascii -FilePath $res -inputObject $Websites
Authentication.ps1
$secpasswd = ConvertTo-SecureString $env:Password -AsPlainText -Force;
$userCredential = New-Object System.Management.Automation.PSCredential ($env:ApplicationId, $secpasswd)
Add-AzureRmAccount -TenantId $env:TenantId -ServicePrincipal -SubscriptionId $env:SubscriptionId -Credential $userCredential
Get-AzureRmSubscription –SubscriptionId $env:SubscriptionId | Select-AzureRmSubscription
It is unsafe for you to save your account information in script. I suggest you could store these to App Setting. You could find it Your function app-->Settings-->Application settings-->Manage application settings-->App settings and key-value pairs for the settings SP_USERNAME, SP_PASSWORD, and TENANTID, SubscriptionId(You also could use other values or more key pairs).
Modify your script as below:
# Set Service Principal credentials
# SP_PASSWORD, SP_USERNAME, TENANTID are app settings
$secpasswd = ConvertTo-SecureString $env:SP_PASSWORD -AsPlainText -Force;
$mycreds = New-Object System.Management.Automation.PSCredential ($env:SP_USERNAME, $secpasswd)
Add-AzureRmAccount -ServicePrincipal -Tenant $env:TENANTID -Credential $mycreds;
Get-AzureRmSubscription –SubscriptionId $env:subscriptionId | Select-AzureRmSubscription
When you want to modify your account information, you don't need modify your script, you only need modify app setting. You could modify app setting by using Azure CLI.
Yes. You can import custom powershell modules.
Create a shared directory e.g. bin under D:\home\site\wwwroot
Copy module to the shared directory
Call Import-Module SharedDir\MyModule.psm1 or SharedDir\MyScript.ps1 or SharedDir\MyModule.psd1 or SharedDir\MyLib.dll
Also, here is a sample that might help.

DSC Azure Install exe as an administrator

I'm using a Resource Manager template in azure to create a VM and using a DSC extension to install a executable once the VM has been created. I have the fundamentals working ie it downloads my file to a directory and installs a test executable. This particular executable is installed at a machine level.
The executable I need to to install must be installed at a user level, not machine level.
I've tried a couple of approaches.
$username = 'username'
$password = 'password'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Start-Process "C:\Deployment\installer.exe" -Credential $credential -ArgumentList ' /S -noprofile -command &{Start-Process -verb runas}'
I've also tried starting another process
$password = convertto-securestring "password" -asplaintext -force
$psi = new-object "Diagnostics.ProcessStartInfo"
$psi.UseShellExecute = $false
$psi.UserName = "username"
$psi.Password = $password
$psi.FileName = $dest
$psi.RedirectStandardOutput = $true
$psi.Arguments = " /S"
$proc = [Diagnostics.Process]::Start($psi)
$result = $proc.StandardOutput.ReadToEnd()
$proc.WaitForExit()
I've also tried a CustomExtension in the Azure Resource Template and still the same.