How to dynamically deploy azure function via blob zip file via API - c#

I want to deploy the C# azure timer trigger function in the function app. I have zip files in my storage container in azure. Now I want to use that zip to deploy timer trigger functions in the function app. This process needs to complete by calling rest API. So that we can deploy as many functions as want dynamically.
I have tried it by powershell script. But for some reason in azure runbook, some powershell command is not supported. So that I want to make it possible via Rest API.

I have tried it by powershell script. But for some reason in azure runbook, some powershell command is not supported.
As an alternative approach, I have tried this using Azure PowerShell and I could able to achieve this using Invoke-WebRequest where it downloads the content to the local folder and then use Publish-AzWebapp to push deployment from the uploaded .zip file. For demonstration purposes I have deployed 3 function apps using the below script.
$context = New-AzStorageContext -StorageAccountName "<STORAGE_ACCOUNT_NAME>" -StorageAccountKey "<STORAGE_ACCOUNT_KEY>"
$a = Get-AzStorageBlob -Context $context -Container "<CONTAINER_NAME>"
for($i=0; $i -le $a.Count-1; $i++)
{
$Uri = "https://<STORAGE_ACCOUNT_NAME>.blob.core.windows.net/<CONTAINER_NAME>/"+$a[$i].Name
$Outfile = "/home/*****/"+$a[$i].Name
Invoke-WebRequest -Uri $Uri -OutFile $Outfile
Publish-AzWebapp -ResourceGroupName <RESOURCE_GROUP> -Name $a[$i].Name.substring(0, ($a[$i].Name).IndexOf(".")) -ArchivePath $a[$i].Name
}
RESULTS:

Related

How to script azure b2c applications creation

I need to create bunch of azure b2c application with powershell scripts.
A powershell script to perform steps described here
https://learn.microsoft.com/it-it/azure/active-directory-b2c/tutorial-register-applications
thank you
Currently, it is only possible to manage B2C policies programmatically. Since B2C Custom Policies went GA, it is now possible to create custom policies using PowerShell.
Refer this: https://stackoverflow.com/a/56252795/10571855
However, the feature request for programmatic app mgmt is here. Please vote for it so that we can let you know when it is available for preview.
You can use PowerShell AzureADPreview 2.0 module to create applications.
Full doc is here: AzureADPreview 2 docs
I had no success to install this module to "old" PowerShell (5.x) so I gave a shot to the 'new' PowerShell 7 (Core). The only issue with PowerShell 7 and AzureAD module is that Connect-AzureAD uses a cryptographic function which is not in .NET Core, so you must import the AzureADPreview module using the -UseWindowsPowerShell option.
Here is a sample, works with PowerShell 7:
Install-Module AzureADPreview
Import-Module AzureADPreview -UseWindowsPowerShell
$tenantId = "yourb2ctenant.onmicrosoft.com"
# Note: this will interactively ask your credentials.
# If you want to run this unattended, use the -Credential parameter with a PSCredential object with a SecureString
Connect-AzureAD -TenantId $tenantId
# ready to go
#list your all apps
Get-AzureADApplication
# examine one of you app and get ideas
$application = Get-AzureADApplication -ObjectId af46a788-8e55-4301-b2df-xxxxxxxxx
# create and application
$applicationName = "yourappname"
$application = New-AzureADApplication -DisplayName $applicationName -PublicClient $true etc

How to Install SharePoint PowerShell Module inside C# for Azure Function App

Just to manage expectations, I am new to PowerShell and to Azure Functions.
Since Azure Functions 2.x no longer supports PowerShell so I am trying to run my PowerShell scripts which requires SPO modules from C# (code below) I am having trouble running the Azure Function App because the PowerShell scripts needed the SPO modules. Anybody who knows how to install the needed modules inside C# PowerShell Instance like Runspace or anything the like? I am even on the right track here? Any comments is highly appreciated. Thank you all.
Sample Code:
[FunctionName("TestFunction")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
{
using (PowerShell PowerShellInstance = PowerShell.Create())
{
var script = #"
Install-Module Microsoft.Online.SharePoint.PowerShell
Install-Module SharePointPnPPowerShellOnline
$url = '<SharePoint Url>'
$ListName = '<List Name>'
Connect-PnPOnline -Url $url -UseWebLogin
$Fields = Get-PnPField -List $ListName
$Items= Get-PnPListItem -List $ListName -PageSize 5000
$RowCtr = 1;
foreach($item in $items.FieldValues)
{
#do something
$RowCtr++;
}
";
PowerShellInstance.AddScript(script);
var results = PowerShellInstance.Invoke();
//some other codes
}
}
You can use Runspace within an Azure Function as shown in this example, lines 93-98. For modules, you can include them as part of the payload you deploy to your function app (recommended), or install them using Kudu.
Once you upload your modules via the payload or Kudo, your script should work with a few modifications. The modules can be directly downloaded from the https://www.powershellgallery.com/ using Save-Module.
After that, your script should work with a few modifications. According to https://learn.microsoft.com/en-us/powershell/module/sharepoint-pnp/connect-pnponline?view=sharepoint-ps, -UseWebLogin is browser based. Alternatively, you can use the -Credentials parameter. Here is how you build a PSCredential object:
$secPassword = ConvertTo-SecureString "StringPassword" -AsPlainText -Force
$credential = [System.Management.Automation.PSCredential]::new("userName", $secPasswd)
Update on 1/23/20:
As of November 2019, PowerShell in Functions has GA-ed and it is available in Functions V2 and V3, for more information, please visit https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell
To have your PowerShell function app install dependencies from the https://www.powershellgallery.com/, you can use our managed dependencies feature. For more info, please visit https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-powershell#dependency-management.
Cheers,
Francisco

Powershell CreateFromDirectory Process cannot access file because it is being used by another process

I have massive 500GB index files on a Windows Server 2012R2 which are being constantly updated by an application.
I have to zip the file using PowerShell, but when I try to zip it using the following snippet of code I get this exception:
Exception calling "CreateFromDirectory" with "4" argument(s): "The process cannot access the file 'E:\Program Files (x86)\Application Folder\File\Status.FCS' because it is being used
by another process."
$zip = "E:\Folder\File.zip"
$can = "E:\Program Files (x86)\Application Folder\File
Import-Module AWSPowerShell
# functions
function ZipFiles( $zipfilename, $sourcedir )
{
Add-Type -Assembly System.IO.Compression.FileSystem
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
[System.IO.Compression.ZipFile]::CreateFromDirectory($sourcedir,
$zipfilename, $compressionLevel, $false)
}
ZipFiles $zip $can
I don't have any issues if I am compressing the files using the Windows GUI, but problem seems to happen only when I am using a PowerShell script. Also if I stop application services, the PowerShell script works fine (which I can't do in prod environment).
One of the solution is to copy folder with 500Gb of index and compress it (which should work) but I don't have enough disk space on my Windows server to do so.
So is there any solution to compress the file while it is write locked using PowerShell script?
you need to set a different directory for the zip file : [System.IO.Directory]::SetCurrentDirectory($inPath)
so
Function ZipFiles( $zipFileName, $pathTarget )
{
Add-Type -Assembly System.IO.Compression.FileSystem
# Emplacement de sortie
[System.IO.Directory]::SetCurrentDirectory($inPath)
$compressionLevel = [System.IO.Compression.CompressionLevel]::Optimal
[System.IO.Compression.ZipFile]::CreateFromDirectory($pathTarget, $zipFileName, $compressionLevel, $false)
}

Using C# to execute Powershell command (azureVM)

I'm trying to develop a .Net form application to manage azure VMs in C# using Powershell cmdlets. I'll have to use the Azure module to get this working.
One of the cmdlet will be Add-AzureAccount
My question is how can I include this module (Azure) in C# project ?
In the comment section, #Prageeth Saravanan gave a useful link on how integrate PowerShell in C#.
https://blogs.msdn.microsoft.com/kebab/2014/04/28/executing-powershell-scripts-from-c/
Quick example :
First I had to include these refs :
System.Management.Automation
System.Collections.ObjectModel
Note : You need to add a NuGet package for "Management.Automation". Just type "System.Management.Automation" you'll find it.
C# code:
//The first step is to create a new instance of the PowerShell class
using (PowerShell powerShellInstance = PowerShell.Create()) //PowerShell.Create() creates an empty PowerShell pipeline for us to use for execution.
{
// use "AddScript" to add the contents of a script file to the end of the execution pipeline.
// use "AddCommand" to add individual commands/cmdlets to the end of the execution pipeline.
powerShellInstance.AddScript("param($param1) $d = get-date; $s = 'test string value'; $d; $s; $param1; get-service");
// use "AddParameter" to add a single parameter to the last command/script on the pipeline.
powerShellInstance.AddParameter("param1", "parameter 1 value!");
//Result of the script with Invoke()
Collection<PSObject> result = powerShellInstance.Invoke();
//output example : #{yourProperty=value; yourProperty1=value1; yourProperty2=StoppedDeallocated; PowerState=Stopped; OperationStatus=OK}}
foreach (PSObject r in result)
{
//access to values
string r1 = r.Properties["yourProperty"].Value.ToString();
}
}
Hope this helps!
We could use PowerShell cmdlets Import-module to add corresponding modules to the current session. We could use force parameter to re-import a module into the same session.
Import-module -name azure -force
The import thing is that the imported module need to be installed on the local computer or a remote computer. So if we want to execute Azure PowerShell cmdlets from C# project that we need to make sure that Azure PowerShell are installed. We can use install-module AzureRM or Azure more details please refer to the Get Started Azure PowerShell cmdlets. In the Azure VM, Azure PowerShell is installed by default.
About how to call PowerShell command or PS1 file using C# please refer to Prageeth Saravanan mentioned link or another SO Thread.

Create a ZIP archive with PowerShell and Windows tools

I would like to backup data of client computers with PowerShell. To do so I create a ZIP archive of the requested data which basically is no problem at all. But when it comes to special characters which use Unicode or the users build very long path names I run into trouble. I have tried different things now but haven’t found a solution yet. My client computers run Windows 10 (Build 1511). Installing the anniversary update (Build 1607) isn’t a solution due to other dependencies. Also the usage of 3rd party software to create ZIP files can’t be one.
Below are three methods I’ve found and tried already. They all have the same problems in common: when it comes to long path names they immediately stop the execution or they just skip the rest of the folder structure.
1. Create a ZIP file with PowerShell V5 CmdLet Expand-Archive
$Target = "C:\Temp\Test.zip"
$Source = "C:\Test"
Compress-Archive -Path $Source -DestinationPath $Target
2. Create a ZIP file with .net class
Add-Type -assembly "system.io.compression.filesystem"
$Target = "C:\Temp\Test.zip"
$Source = "C:\Test"
[io.compression.zipfile]::CreateFromDirectory($Source, $Target);
3. Create a ZIP file with Windows Explorer (Compressed Folders)
$Source = Get-ChildItem "C:\Test" -Recurse
$Target = "C:\Temp\Test.zip"
if (-not (Test-Path $Target)) {
Set-Content $Target ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
(dir $Target).IsReadOnly = $false
}
$objShell = New-Object -Com Shell.Application
$objZIP = $objShell.NameSpace($Target)
foreach($File in $Source) {
$objZIP.CopyHere($File.FullName)
Start-sleep -milliseconds 500
}
Then I found out, that it should be possible to access the local drives via UNC namespace which could look like \\?\C:\Test. But this doesn’t work with my Windows 10 build 1511 version. With build 1607 it is possible. What I don’t understand: why? I tried it with installing the latest .net version 4.6.2 on build 1511 but the problem still exists.
Can anybody help me with the access to (local) UNC namespaces or creating ZIP archives?
to access UNC path, use the $ characters to design drive
like \\computername\c$\path\path\file.txt
i use the .Net function because of compatibility with powershell v2
[IO.Compression.ZipFile]::CreateFromDirectory($SourcesFolder, $zipTempPath, $CompressionLevel, $False)
i use it with long UNC path with no problems.

Categories

Resources