Azure Automation Hybrid-Worker Get-AutomationPSCredential for PowerShell 7 - azure

We are moving a few Azure Automation Hybrid-worker scripts to PowerShell 7.1. In doing so one of the commands that work in PowerShell 5.1 is: [PSCredential] $AutomationCredential = Get-AutomationPSCredential -Name 'abcdef'. When we try the same command in PowerShell 7.1 we get an error The 'Get-AutomationPSCredential' command was found in the module 'Orchestrator.AssetManagement.Cmdlets', but the module could not be loaded. For more information, run 'Import-Module Orchestrator.AssetManagement.Cmdlets'
We have added the Import-Module to the code but we get Could not load file or assembly 'JobRuntimeData.Client, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
We do find Orchestrator.AssetManagement.Cmdlets the on the hybrid-worker, in the sandbox area. We know that this module is loaded when the hybrid-worker is installed (https://learn.microsoft.com/en-us/azure/automation/shared-resources/modules#internal-cmdlets).

Based on the Microsoft official document
The 'Get-AutomationPSCredential is currently supported till Azure powershell 6.6.0
NOTE: Powershell 7.1 is still in preview so this may be the reason for the error .
Please refer this MS DOC for more information.

We are assuming the Orchestrator.AssetManagement.Cmdlets is bugged at this point, but have not found anything to say that it is. To get around it we were going to use a runbook variable to store the password, but it needs the cmdlet to actually decode a secret/hidden value.
In the end, we used a key vault to store the password. The following is what was used as a workaround.
$User = "AutomationUser"
$KeyVaultName = "KeyVault"
try {
$Password = (ConvertTo-SecureString (Get-AzKeyVaultSecret -VaultName $KeyVaultName -Name $User -AsPlainText) -AsPlainText -Force)
[PSCredential] $AutomationCredential = New-Object System.Management.Automation.PSCredential($User, $Password)
}
catch {
$ErrorMessage = "Unable to retrieve credentials for user: [${$User}]. $_"
throw $ErrorMessage
BREAK
}

Related

Accessing Azure Storage Table from Azure Function App (PowerShell)

I want to use the following code in a Azure Function powershell app:
Add-AzTableRow `
-table outputTable`
-partitionKey $partitionKey `
-rowKey ($record.id) -property #{"userId" = "001";}
I'm using this documentation as a guide. However, this guide uses Install-Module AzTable. Since I am using a Function App to run this code on a timer, I can't install the module on run time. I've followed this question/answer. I've added this to `requirements.psd1':
#{
# For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'.
# To use the Az module in your function app, please uncomment the line below.
#'Az' = '8.*'
AzTable = '2.*'
}
When I run the code I get the following error:
[Error] ERROR: The 'Add-AzTableRow' command was found in the module 'AzTable', but the module could not be loaded. For more information, run 'Import-Module AzTable'.
Could someone please give me some insight on what I'm doing wrong? I want to be able to update and query the table from the Function App without any user input.
Edit:
I have added 'Az' = '8.*' and 'AzTable' = '2.*'. I let the function install the resource by running and waiting. I'm now getting the error:
[Error] ERROR: The term 'Add-AzTableRow' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I'm not sure why I'm getting this error because Add-AzTableRow is apart if the AzTable module.
The AzTable module requires the Az Module:
It requires latest PowerShell Az module installed
https://www.powershellgallery.com/packages/AzTable/2.0.1
But currently the install of the Az module is disabled in your requirements.psd1:
Remove # from #'Az' = '8.*' = 'Az' = '8.*'
After that the machine behind the function will install the required module and the code will be able to load it/acces the functions.
Note if you "activate" a module the first time, run your code and maybe you still get the error messge -> script got started before module install completed... so simply wait some minutes and retry.
Run VS Code as an Administrator. Open the Azure PowerShell Functions Project in the VS Code.
In the VS Code Terminal of project Workspace/Path, run the below cmdlets one by one:
Install-Module Az
Import-Module Az
Install-Module AzTable -Force
Import-Module AzTable
Created Azure Functions PowerShell HTTP Trigger Function and written the code with the reference of this MS Doc:
run.ps1
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
# Interact with query parameters or the body of the request.
Connect-AzAccount -Tenant '<Tenant-Id>' -SubscriptionId '<Subscription-Id>'
Set-AzContext -Subscription "<Subscription-Id>"
$resourceGroup = "HariTestRG"
$storageAccountName ="store365rvi7b3lmoq"
$storageAccount=Get-AzStorageAccount -ResourceGroupName $resourceGroup -Name $storageAccountName
$ctx = $storageAccount.Context
Write-Host $ctx.ConnectionString
$tableName = "pshkrishtesttable"
$cloudTable = (Get-AzStorageTable –Name $tableName –Context $ctx).CloudTable
Write-Host $cloudTable.Name
$partitionKey1 = "partition2"
Write-Host "Partition Key"
# add a row
Add-AzTableRow `
-table $cloudTable `
-partitionKey $partitionKey1 `
-rowKey ("India") -property #{"username"="Jashu";"userid"=598}
Write-Host "Table Row Added"
$TableRows = Get-AzTableRow -table $cloudTable
Write-Host $TableRows | Format-Table
$body = "Hello Krishna, This HTTP triggered function executed successfully."
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = [HttpStatusCode]::OK
Body = $body
})
requirements.psd1:
#{
'Az' = '8.*'
'Az.Storage' = '4.10.0'
'AzTable' = '2.1.0'
}
Result:
Note: If you are running the PowerShell Function with these modules for the first time, it will take some time during the runtime/execution.

PS Azure automation runbook ; How to Mount Azure File Share?

Trying to mount Azure FS from Powershell runbook in Azure Automation.
Via username and key
$UserName = "localhost\trex4xfs"
$Key = "Zav---mykey-----1Tdw=="
$RemotePath = "\\myshare.file.core.windows.net\mainfs"
$MapDrive = "z:"
Get-Command -Name *SmbMapping* | ft
[securestring]$pass = ConvertTo-SecureString $key -AsPlainText -Force
$credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $UserName, $pass
new-psdrive -name T -PsProvider FileSystem -root $RemotePath -credential $credential
Get-PSDrive | ft
echo "--------now import smb"
Import-Module smbshare
echo "--------now smb"
New-SmbMapping -LocalPath $MapDrive -RemotePath $RemotePath -UserName $UserName -Password $Key
Above works great on "plain Powershell on Windows"
Tried
Runbook with 5.1 and 7.1 PS version
new-psdrive (error: This function is not supported on this system )
New-SmbMapping (error 7.1: The 'New-SmbMapping' command was found in the module 'SmbShare', but the module could not be loaded. For more information, run 'Import-Module SmbShare'
New-SmbMapping (error 5.1: Cannot connect to CIM server. The specified service does not exist as an installed service. )
Import-Module smbshare (error Failed to generate proxies for remote module 'smbshare'. Cannot overwrite the item C:\Users\Client\Temp\tmp_5t22mi1k.oh0\remoteIpMoProxy_smbshare_2.0.0.0_localhost_f29e4e95-e8cf-4256-a4db-fc9381c6563c.format.ps1xml with itself.)
New-CimSession (error: The specified service does not exist as an installed service.)
Seem to be related to New-CimSession not available on Azure Automation runbook
other questions related to this:
Azure Runbook - Get a file from Azure File System Storage
Not able to access Azure FileShare Storage container from Azure Automation Runbook
Map a Azure Fileshare to Azure Runbook local drive to use as temporary storage
One of the related question which you have shared already provides the answer (i.e., this one) which basically says to use hybrid runbook worker in your use case scenario.

How can I get a list of Azure AD Users in my PowerShell script within my Azure Function App?

Some context: I have a PowerShell script that gets information about users and their licenses on Azure, and then saves that information to CSV file. It works locally. My goal is to have this script automatically run on Azure (I'm trying to do it in an Azure Function App) once a month, and then have the created CSV file be emailed to a specified email. However all I want to figure out right now is how to get the list of users so that the script can at least just run without errors.
I have very little experience with PowerShell and Azure Function Apps, so I'm stuck on a few errors I'm getting. I have spent the last few days troubleshooting to no luck.
Here is the beginning of the script that I can run from my local PowerShell:
Function main()
{
#Clean up session
Get-PSSession | Remove-PSSession
#Connect AzureAD from PowerShell
Connect-MsolService
#Set output file
$ExportCSV=".\DetailedO365UserLicenseReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv"
$ExportSimpleCSV=".\SimpleO365UserLicenseReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv"
#FriendlyName list for license plan and service - txt file on local computer
$FriendlyNameHash=Get-Content -Raw -Path .\LicenseFriendlyName.txt -ErrorAction Stop | ConvertFrom-StringData
#txt file on local computer
$ServiceArray=Get-Content -Path .\ServiceFriendlyName.txt -ErrorAction Stop
#Hash table declaration
$Result=""
$Results=#()
$output=""
$outputs=#()
$LicensedUserCount=0
#Get all licensed users
Get-MsolUser -All | where{$_.islicensed -eq "true"} | Foreach{
#this is another function that handles grabbing the user info and writing it to the CSV file
Get_UsersLicenseInfo
$LicensedUserCount++
}
. main
With this script above, it requires some user input for entering credentials. I want this script to be able to run automatically in Azure without any user input, so I've been trying to modify it to do that. I found out that any commands with 'Msol' in the name don't work in Azure Function Apps/Powershell Core, so I found a different module that apparently does work.
This is where I'm currently at with the script to be run in my Azure Function App:
Import-Module AzureAD
Function main()
{
#Clean up session
Get-PSSession | Remove-PSSession
$password = ConvertTo-SecureString "{my password here}" -AsPlainText -Force
$UserCredential = New-Object System.Management.Automation.PSCredential ("myusernamehere", $password)
Connect-AzureAD -Credential $UserCredential
#Set output file
$ExportCSV=".\DetailedO365UserLicenseReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv"
$ExportSimpleCSV=".\SimpleO365UserLicenseReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv"
#FriendlyName list for license plan and service - hash table here
$FriendlyNameHash= #{AAD_BASIC = "Azure Active Directory Basic"; AAD_PREMIUM= "Azure Active Directory Premium"; AAD_PREMIUM_P1= "Azure Active Directory Premium P1"; AAD_PREMIUM_P2= "Azure Active Directory Premium P2" }
#array of strings, used when getting user info
$ServiceArray= "MCOEV", "Cloud PBX", "MCOPSTN2", "PSTN International", "mcomeetadv"
#Hash table declaration
$Result=""
$Results=#()
$output=""
$outputs=#()
$LicensedUserCount=0
Get-AzureADUser -All | where{$_.islicensed -eq "true"} | Foreach{
Get_UsersLicenseInfo
$LicensedUserCount++}
}
. main
First of all I'm not sure if I even need to authenticate if this script is running from within my Azure account. Second of all, and my main issue, is that when I try to run this script in my Azure Function App, I get this error:
snippet of the azure error
If the picture doesn't work, it says:
The Function app may be missing a module containing the 'Connect-AzureAD' command definition. If this command belongs to a module available on the PowerShell Gallery, add a reference to this module to requirements.psd1. Make sure this module is compatible with PowerShell 7. For more details, see https://aka.ms/functions-powershell-managed-dependency. If the module is installed but you are still getting this error, try to import the module explicitly by invoking Import-Module just before the command that produces the error: this will not fix the issue but will expose the root cause.
2021-06-08T16:48:00.377 [Error] ERROR: The term 'Connect-AzureAD' is not recognized as the name of a cmdlet, function, script file, or operable program.Check the spelling of the name, or if a path was included, verify that the path is correct and try again.Exception
I get that same error for the line with 'Get-AzureADUser' as well. I followed this guide: https://tech.nicolonsky.ch/azure-functions-powershell-modules/ to add the AzureAD module to my managed dependencies, but I still get that same error.
If anything needs clarification, let me know. Any help is appreciated!
Actually, AzureAD needs to be imported a bit differently - it's been a problem for a while per this github issue. This seemed to work for most people:
Setting the application to run as x64 bit: Function App>
Configuration > General Settings > Platform > 64 Bit
Setting the app to run on Powershell 7 instead of 6 on this thread
Use: Import-Module AzureAD -UseWindowsPowerShell

The term 'Register-AzResourceProvider' is not recognized as the name of a cmdlet

Hi I am trying to teach myself Azure and I'm following this guide: https://learn.microsoft.com/en-us/learn/modules/intro-to-governance/2-azure-policy. I'm on a windows 10 with $PSVersionTable.PSEdition = Desktop I messaged Microsoft support, but no one has responded. When I try to run
# Register the resource provider if it's not already registered
Register-AzResourceProvider -ProviderNamespace 'Microsoft.PolicyInsights'
I get
Register-AzResourceProvider : The term 'Register-AzResourceProvider' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that
the path is correct and try again.
I've checked off having Azure powershell installed
if ($PSVersionTable.PSEdition -eq 'Desktop' -and (Get-Module -Name AzureRM -ListAvailable)) {
Write-Warning -Message ('Az module not installed. Having both the AzureRM and ' +
'Az modules installed at the same time is not supported.')
} else {
Install-Module -Name Az -AllowClobber -Scope CurrentUser
}
Any help with this would be greatly appreciated.
To solve the issue, try to follow the steps below.
1.Open a new powershell session via Run as administrator, then run the command below.
Install-Module -Name Az -AllowClobber -Scope AllUsers -Force
2.After installing the module, close the administrator session and open a new normal powershell session, then login your user account which has the permission to register the provider, e.g. Owner of the subscription.
Connect-AzAccount
3.Then register the provider.
Register-AzResourceProvider -ProviderNamespace 'Microsoft.PolicyInsights'
Note: If the issue is still existing, use Get-Module to check if the Az.Resources module was imported in this powershell session(normally it will be imported automatiocally), if not, you could use Import-Module -Name Az.Resources -Force to import it manually.
The command you are trying to use is not a PowerShell command. The command you are looking for should begin with either a Get- or Set- prefix.

How to create a Microsoft Team using a Queue Triggered Azure Function writed in PowerShell?

I want to create a Team by using an azure function triggered by an Azure Queue.
Unfortunetly when I run the code it is not working inside the Azure Function.
I'm wondering. Is there a way to create a Microsoft Team using PowerShell inside an Azure Function ?
Import-module MicrosoftTeams
$group = New-Team -MailNickname "teamTitle" -displayname "teamTitle" -Visibility "private"
Add-TeamUser -GroupId $group.GroupId -User "user#etc.com"
New-TeamChannel -GroupId $group.GroupId -DisplayName "General"
Working locally. Not working within the Azure Function.
Bellow the error i'm getting :
ERROR: Import-Module : The specified module 'MicrosoftTeams' was not loaded because no valid
module file was found in any module directory. At D:\home\site\wwwroot\CreateTeam\run.ps1:3
char:1 + Import-Module MicrosoftTeams + [...]
Thank you
Based on the error message, your Function app does not have the MicrosoftTeams module installed. You need to include a reference to this module to the requirements.psd1 file (see https://learn.microsoft.com/azure/azure-functions/functions-reference-powershell#dependency-management for more details).
Currently this module is not yet natively integrated into the azure functions under powershell
To see all the available packages go in App Service -> Advanced Tools -> DebugConsole -> Powershell and run :
Write-Output ‘Getting PowerShell Module’
$result = Get-Module -ListAvailable |
Select-Object Name, Version, ModuleBase |
Sort-Object -Property Name |
Format-Table -wrap |
Out-String
Write-output `n$result
To manually add a package, It is necessary to create a directory "Module" At the same level as the directory of the function, They will be automatically preloaded.
(https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell step "Function app-level Modules folder")
After installation of the module. use below code in your script to automate the process.
$securedpassword = ConvertTo-SecureString $Password -AsPlainText -Force
$mycredentials = New-Object System.Management.Automation.PSCredential ($Username, $securedpassword )
$res = Connect-MicrosoftTeams -Credential $mycredentials

Resources