Azure Runbook Running Sql Query: The target principal name is incorrect. Cannot generate SSPI context." - sql

Hi I am trying to run a SQL query on one of my databases using an Azure Runbook. My setup is listed below. When I test this, I get the error The target principal name is incorrect. Cannot generate SSPI context." I have looked around and have not found anything related to an Azure setup. Does anyone have any ideas?
$myCred = Get-AutomationPSCredential -Name 'my-cred'
$userName = $myCred.UserName
$securePassword = $myCred.Password
$password = $myCred.GetNetworkCredential().Password
#Query to execute
# Invoke to Azure SQL DB
invoke-sqlcmd2 -ServerInstance $ServerName -Database $DatabaseName -Credential $SQLServerCred -Query $SqlQuery -Encrypt

As mentioned in the comment, looks you did not set $SQLServerCred before.
Try:
$myCred = Get-AutomationPSCredential -Name 'my-cred'
$userName = $myCred.UserName
$securePassword = $myCred.Password
$SQLServerCred = New-Object System.Management.Automation.PSCredential($userName , $securePassword)
#Query to execute
# Invoke to Azure SQL DB
invoke-sqlcmd2 -ServerInstance $ServerName -Database $DatabaseName -Credential $SQLServerCred -Query $SqlQuery -Encrypt

Related

Azure Monitoring Database performance

I need to compile the following information: "a scheduled report that shows the DB environment state. From free space to performance, failed jobs and anything else that can cause a DB not to function correctly."
I keep getting referred to the same learn.microsoft links but for some reason i just get progressively more confused.
Can someone please help me with a step by step instruction on how to achieve the above mentioned?
All our DBs are on Azure VMs.
I tried Chat GPT for the disk sizes and it gave me a Power Shell code. <
# Connect to your Azure account
Connect-AzAccount
# Get a list of all virtual machines in your subscription
$vms = Get-AzVM
# Loop through the list of virtual machines
foreach ($vm in $vms) {
# Get the details of each virtual machine
$vmName = $vm.Name
$vmSize = $vm.HardwareProfile.VmSize
# Get a list of all disks attached to the virtual machine
$disks = Get-AzDisk | Where-Object { $_.ManagedBy -eq $vm.Id }
# Loop through the list of disks
foreach ($disk in $disks) {
# Get the details of each disk
$diskName = $disk.Name
$diskSize = $disk.DiskSizeGB
$diskType = $disk.StorageAccountType
# Print the virtual machine, disk, and disk size information
Write-Output "VM Name: $vmName"
Write-Output "VM Size: $vmSize"
Write-Output "Disk Name: $diskName"
Write-Output "Disk Size: $diskSize GB"
Write-Output "Disk Type: $diskType"
Write-Output ""
}
}
\>
I could not get free space information or Database information this way.
Your script is working but you are retrieving information about the VMs, not about the SQL Server that is stored within the VMs.
You need to login into the SQL Server inside the VM and run the query that you want:
# Load the Azure RM module
Import-Module AzureRM
# Login to Azure
Login-AzureRmAccount
# Get a list of all Azure VMs
$vms = Get-AzureRmVM
# Loop through each VM
foreach ($vm in $vms) {
# Get the VM's IP address
$ipAddress = (Get-AzureRmPublicIpAddress -ResourceGroupName $vm.ResourceGroupName -Name ($vm.Name + '-ip')).IpAddress
# Connect to SQL Server on the VM
$connectionString = "Server=$ipAddress;Database=master;User ID=<username>;Password=<password>"
$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
$connection.Open()
# Execute the SELECT ##VERSION query
$command = $connection.CreateCommand()
$command.CommandText = "SELECT ##VERSION"
$reader = $command.ExecuteReader()
# Display the result
while ($reader.Read()) {
Write-Output $reader.GetValue(0)
}
# Close the connection
$connection.Close()
}
Note that you will need to replace <username> and <password> with the actual SQL Server login credentials for each VM.
Replace the "SELECT ##VERSION" with the query that investigates:
DB environment state
free space
performance
failed jobs
anything else...

How can I transfer a subscription in API Management from one user to another in Azure PowerShell?

I want to transfer control on API Management subscriptions from one user to another in case the original user e.g. left the company or changed job roles.
Have email address of source and target user prepared, adapt and use these Azure PowerShell commands:
$ctx = New-AzApiManagementContext -ResourceGroupName {your-resource-group} -ServiceName {your-APIM-service-name}
$from = Get-AzApiManagementUser -Context $ctx -Email "from.user#my-company.com"
$to = Get-AzApiManagementUser -Context $ctx -Email "to.user#my-company.com"
Get-AzApiManagementSubscription -Context $ctx -UserId $from.UserId | ConvertTo-Json | Set-Content ./SubscriptionDump.json
Get-Content .\SubscriptionDump.json | ConvertFrom-Json | %{Set-AzApiManagementSubscription -Context $ctx -SubscriptionId $_.SubscriptionId -UserId $to.UserId}

Automate Powershell Script to connect to MSOnline while MFA is applied

Thanks in advance.
Quick brief, I work in a team managing multiple Microsoft CSPs (Partner Centers), every now and then somebody asks us to run a script that does specific activities or grab specific info from all 30 CSPs we manage and all customers under them.
Previously we used to keep all usernames, passwords, TenantIDs, WebApp IDs in a CSV file and we create a script that runs on every raw to get the required info for each CSP Automatically without prompting credentials using below command:
$credential = (New-Object –TypeName System.Management.Automation.PSCredential –argumentlist $AdminName ,(ConvertTo-SecureString $AdminPassword –AsPlainText –Force))
And then call it in all modules like the below:
#MSonline
Connect-Msolservice –Credential $Credential
#ExchangeOnline
$session = New-PSSession –ConfigurationName Microsoft.Exchange –ConnectionUri https://outlook.office365.com/powershell-liveid?DelegatedOrg=$Customerdomain –Credential $credential –Authentication Basic –AllowRedirection
Import-PSSession $Session
#Partner Center
Add-PCAuthentication -cspappID $NAtive_clientid -cspDomain $domain -credential $credentials
Connect-MsolService -Credential $credentials
Then MFA was applied on all CSPs, though secure, it presented a problem with automating our scripts. Every time we're asked to run a script we would have to login manually at least 1 time to enter our MFA credentials to be able to run the script on each CSP individually.
The Modules we usually connect to are:
PartnerCenter
MSOnline
CsOnline
AzureRM
AzureAD
Microsoft provided steps to work around this by using secure API Modules: https://learn.microsoft.com/en-us/powershell/partnercenter/secure-app-model?view=partnercenterps-1.5
I've created New APPs with new secrets and call backs , managed to get refresh token and integrated it in PartnerCenter module successfully as follows:
Connect-PartnerCenter -ApplicationId $NAtive_clientid -RefreshToken $refresh_token
Now I'm tying to do the same for the other Modules I'm addressing, as per the above document I could do the same for MS Online and for Azure AD simply by getting 3 other tokens (Graph Token , Azure AD token and Azure token)
$credential = Get-Credential
$refreshToken = 'Your-Refresh-Token-Value'
$azureToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://management.azure.com/ -Credential $credential -TenantId '<Your Tenant Id>'
$graphToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://graph.microsoft.com -Credential $credential -TenantId '<Your Tenant Id>'
$aadGraphToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://graph.windows.net -Credential $credential -TenantId '<Your Tenant Id>'
#MS Module
Connect-MsolService -AdGraphAccessToken $aadGraphToken.AccessToken -MsGraphAccessToken $graphToken.AccessToken
# Az Module
Connect-AzAccount -AccessToken $azureToken.AccessToken -GraphAccessToken $graphToken.AccessToken -TenantId '<TenantId>'
# AzureRM Module
Connect-AzureRmAccount -AccessToken $azureToken.AccessToken -GraphAccessToken $graphToken.AccessToken -TenantId '<TenantId>'
When Applying this and running the below command I get an error:
New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://management.azure.com/ -Credential $credential -TenantId '<Your Tenant Id>'
New-PartnerAccessToken : Cannot validate argument on parameter 'RefreshToken'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:1 char:38
+ New-PartnerAccessToken -RefreshToken $refreshToken -Resource https:// ...
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [New-PartnerAccessToken], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Store.PartnerCenter.PowerShell.Commands.NewPartnerAccessT
oken
After some investigation I found that the parameter "-resource" no longer exists as per the documentation: https://learn.microsoft.com/en-us/powershell/module/partnercenter/new-partneraccesstoken?view=partnercenterps-3.0
Yet as per the documentation related to MSOnline, it shows I should be able to use it : https://learn.microsoft.com/en-us/powershell/module/msonline/connect-msolservice?view=azureadps-1.0
Now I'm stuck without the resource parameter I can't get the tokens required to use the 3 modules.
My question, is there another way to use App ID, refresh token, secret, Tenant ID to authenticate using powershell without human interference , if not how can I make the above method work for other modules the same way I did with the partner center.
According to my research. if the version of your PartnerCenter module is larger than 2.0.1909.1, it has rplaced the Resource parameter with the Scopes parameter for the Connect-PartnerCenter and New-PartnerAccessToken cmdlets. So please use the following script to get access token
New-PartnerAccessToken -ApplicationId 'xxxx-xxxx-xxxx-xxxx' -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant 'xxxx-xxxx-xxxx-xxxx'

Can't connect to SQL from Powershell

I tried to query my syslogins with this script in powershell. It gives me this error:
"A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not
found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections.
The error shown:
provider: Named Pipes Provider, error: 40 - Could not open a
connection to SQL Server
Remote Access is enabled on the Database I try to connect to.
This is the code im working with:
$conn = New-Object System.Data.SqlClient.SqlConnection
$cmd = New-Object System.Data.SqlClient.SqlCommand
$conn.ConnectionString = "server=servername.hsr.ch;database=mydb;Integrated Security=true;"
$conn.open()
$cmd.Connection = $conn
$cmd.CommandText = "SELECT * FROM syslogins"
$out = $cmd.ExecuteNonQuery()
$conn.close()
print $out

Powershell SMO Can't Connect

I'm having an issue connecting to a SQL Server using SMO when using a ServerConnection. For the last few months this has been working, but now failing. Here is a snippet of the script:
$svrname = "Server"
#Establish Server connection
Write-ColorOutput "Establishing SQL Server Connection to $svrName" "White"
$mysvrConn = new-object Microsoft.SqlServer.Management.Common.ServerConnection
$mysvrConn.ServerInstance=$svrName
$mysvrConn.LoginSecure = $false
$mysvrConn.Login = "Admin"
$mysvrConn.Password = "Password"
$svr = new-object 'Microsoft.SqlServer.Management.SMO.Server' $mysvrConn
However, the following works.
$svrname = "Server"
$svr = new-object ('Microsoft.SQLServer.Management.SMO.Server') $svrname
And the assemblies:
Write-ColorOutput "Loading assemblies" "White"
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SQLServer.Smo") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.ConnectionInfo") | out-null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoEnum") | Out-Null
You almost certainly have permission issues with your SQL login. You are either using the wrong password, or the login does not have the proper creds.
Embarrassingly, when I had this issue, it turned out to be that I had entered the login password incorrectly.
I had expected a specific error stating the login failed. Instead it was the more generic: Failed to connect to server localhost., which threw me off.
Like you, I ran a test with the $LoginSecure = $True which worked, telling me that the connection to the server was fine. Only then did I spot my typo and was on my way to SMO bliss.