Archive
Farewell #Skype. Here’s how their #API worked.
So, with the shutdown of Skype in May 2025, only two months away, there is not much need to hold on tight to our source code for the Skype API. It worked well for us for years on AvatarAPI.com
but with the imminent shutdown, their API will undoubtedly stop working as soon as Skype is shut down, and will no longer be relevant, even if the API stays active for a little while later.
In this post, we’ll take a deep dive into a C# implementation of a Skype user search feature using HTTP requests. This code interacts with Skype’s search API to fetch user profiles based on a given search parameter. We’ll break down the core functionality, security considerations, and potential improvements.
Overview of the SkypeSearch Class
The SkypeSearch class provides a static method, Search, which sends a request to Skype’s search API to retrieve user profiles. It uses an authentication token (SkypeToken) and manages retries in case of failures. Let’s explore its components in detail.
Key Features of the Implementation
- Handles API Requests Securely: The method sets various security protocols (
Ssl3,Tls,Tls11,Tls12) to ensure compatibility with Skype’s API. - Custom Headers for Authentication: It constructs an HTTP request with necessary headers, including
x-skypetoken,x-skype-client, and others. - Manages Rate Limits & Token Refresh: If the API responds with an empty result (potentially due to a
429 Too Many Requestserror), the token is refreshed, and the search is retried up to five times. - Enhances API Response: The method modifies the API response to include an additional
avatarImageUrlfield for each result.
Breaking Down the Search Method
Constructing the API Request
var requestNumber = new Random().Next(100000, 999999);
var url = string.Format(
"https://search.skype.com/v2.0/search?searchString={0}&requestId={1}&locale=en-GB&sessionId={2}",
searchParameter, requestNumber, Guid.NewGuid());
This snippet constructs the API request URL with dynamic query parameters, including:
searchString: The user input for searching Skype profiles.requestId: A randomly generated request ID for uniqueness.sessionId: A newly generated GUID for session tracking.
Setting HTTP Headers
HTTPHeaderHandler wicket = nvc =>
{
var nvcSArgs = new NameValueCollection
{
{"x-skypetoken", token.Value},
{"x-skype-client", "1418/8.134.0.202"},
{"Origin", "https://web.skype.com"}
};
return nvcSArgs;
};
Here, we define essential request headers for authentication and compatibility. The x-skypetoken is a crucial element, as it ensures access to Skype’s search API.
Handling API Responses & Retrying on Failure
if (jsonResponse == "")
{
token = new SkypeToken();
return Search(searchParameter, token, ++maxRecursion);
}
If an empty response is received (potentially due to an API rate limit), the method refreshes the authentication token and retries the request up to five times to prevent excessive loops.
Enhancing API Response with Profile Avatars
foreach (var node in jResponse["results"])
{
var skypeId = node["nodeProfileData"]["skypeId"] + "";
var avatarImageUrl = string.Format(
"https://avatar.skype.com/v1/avatars/{0}/public?size=l",
skypeId);
node["nodeProfileData"]["avatarImageUrl"] = avatarImageUrl;
}
After receiving the API response, the code iterates through the user results and appends an avatarImageUrl field using Skype’s avatar service.
using System;
using System.Collections.Specialized;
using System.Net;
using System.Text;
using Newtonsoft.Json.Linq;
namespace SkypeGraph
{
public class SkypeSearch
{
public static JObject Search(string searchParameter, SkypeToken token, int maxRecursion = 0)
{
if (maxRecursion == 5) throw new Exception("Preventing excessive retries");
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 |
SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
var requestNumber = new Random().Next(100000, 999999);
var url = string.Format("https://search.skype.com/v2.0/search?searchString={0}&requestId={1}&locale=en-GB&sessionId={2}", searchParameter, requestNumber, Guid.NewGuid());
var http = new HTTPRequest {Encoder = Encoding.UTF8};
HTTPHeaderHandler wicket = nvc =>
{
var nvcSArgs = new NameValueCollection
{
{"x-skypetoken", token.Value},
{"x-skypegraphservicesettings", ""},
{"x-skype-client","1418/8.134.0.202"},
{"x-ecs-etag", "GAx0SLim69RWpjmJ9Dpc4QBHAou0pY//fX4AZ9JVKU4="},
{"Origin", "https://web.skype.com"}
};
return nvcSArgs;
};
http.OverrideUserAgent =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
http.OverrideAccept = "application/json";
http.TimeOut = TimeSpan.FromSeconds(5);
http.HeaderHandler = wicket;
http.ContentType = "application/json";
http.Referer = "https://web.skype.com/";
var jsonResponse = http.Request(url);
if (jsonResponse == "")
{
// In case of a 429 (Too many requests), then refresh the token.
token = new SkypeToken();
return Search(searchParameter, token, ++maxRecursion);
}
var jResponse = JObject.Parse(jsonResponse);
#region sample
/*
{
"requestId":"240120",
"results":[
{
"nodeProfileData":{
"skypeId":"live:octavioaparicio_jr",
"skypeHandle":"live:octavioaparicio_jr",
"name":"octavio aparicio",
"avatarUrl":"https://api.skype.com/users/live:octavioaparicio_jr/profile/avatar",
"country":"Mexico",
"countryCode":"mx",
"contactType":"Skype4Consumer"
}
}
]
}
*/
#endregion
foreach (var node in jResponse["results"])
{
var skypeId = node["nodeProfileData"]["skypeId"] + "";
var avatarImageUrl = string.Format("https://avatar.skype.com/v1/avatars/{0}/public?size=l", skypeId);
node["nodeProfileData"]["avatarImageUrl"] = avatarImageUrl;
}
return jResponse;
}
}
}
Resolving Unauthorized Error When Deploying an #Azure Function via #ZipDeploy

Deploying an Azure Function to an App Service can sometimes result in an authentication error, preventing successful publishing. One common error developers encounter is:
Error: The attempt to publish the ZIP file through https://<function-name>.scm.azurewebsites.net/api/zipdeploy failed with HTTP status code Unauthorized.
This error typically occurs when the deployment process lacks the necessary authentication permissions to publish to Azure. Below, we outline the steps to resolve this issue by enabling SCM Basic Auth Publishing in the Azure Portal.
Understanding the Issue
The error indicates that Azure is rejecting the deployment request due to authentication failure. This often happens when the SCM (Kudu) deployment service does not have the correct permissions enabled, preventing the publishing process from proceeding.
Solution: Enable SCM Basic Auth Publishing
To resolve this issue, follow these steps:
- Open the Azure Portal and navigate to your Function App.
- In the left-hand menu, select Configuration.
- Under the General settings tab, locate SCM Basic Auth Publishing.
- Toggle the setting to On.
- Click Save and restart the Function App if necessary.
Once this setting is enabled, retry the deployment from Visual Studio or your chosen deployment method. The unauthorized error should now be resolved.
Additional Considerations
- Use Deployment Credentials: If you prefer not to enable SCM Basic Auth, consider setting up deployment credentials under Deployment Center → FTP/Credentials.
- Check Azure Authentication in Visual Studio: Ensure that you are logged into the correct Azure account in Visual Studio under Tools → Options → Azure Service Authentication.
- Use Azure CLI for Deployment: If problems persist, try deploying with the Azure CLI:
az functionapp deployment source config-zip \ --resource-group <resource-group> \ --name <function-app-name> \ --src <zip-file-path>
By enabling SCM Basic Auth Publishing, you ensure that Azure’s deployment service can authenticate and process your function’s updates smoothly. This quick fix saves time and prevents unnecessary troubleshooting steps.
Obtaining an Access Token for Outlook Web Access (#OWA) Using a Consumer Account

If you need programmatic access to Outlook Web Access (OWA) using a Microsoft consumer account (e.g., an Outlook.com, Hotmail, or Live.com email), you can obtain an access token using the Microsoft Authentication Library (MSAL). The following C# code demonstrates how to authenticate a consumer account and retrieve an access token.
Prerequisites
To run this code successfully, ensure you have:
- .NET installed
- The
Microsoft.Identity.ClientNuGet package - A registered application in the Microsoft Entra ID (formerly Azure AD) portal with the necessary API permissions
Code Breakdown
The following code authenticates a user using the device code flow, which is useful for scenarios where interactive login via a browser is required but the application does not have direct access to a web interface.
1. Define Authentication Metadata
var authMetadata = new
{
ClientId = "9199bf20-a13f-4107-85dc-02114787ef48", // Application (client) ID
Tenant = "consumers", // Target consumer accounts (not work/school accounts)
Scope = "service::outlook.office.com::MBI_SSL openid profile offline_access"
};
- ClientId: Identifies the application in Microsoft Entra ID.
- Tenant: Set to
consumersto restrict authentication to personal Microsoft accounts. - Scope: Defines the permissions the application is requesting. In this case:
service::outlook.office.com::MBI_SSLis required to access Outlook services.openid,profile, andoffline_accessallow authentication and token refresh.
2. Configure the Authentication Application
var app = PublicClientApplicationBuilder
.Create(authMetadata.ClientId)
.WithAuthority($"https://login.microsoftonline.com/{authMetadata.Tenant}")
.Build();
- PublicClientApplicationBuilder is used to create a public client application that interacts with Microsoft identity services.
.WithAuthority()specifies that authentication should occur against Microsoft’s login endpoint for consumer accounts.
3. Initiate the Device Code Flow
var scopes = new string[] { authMetadata.Scope };
var result = await app.AcquireTokenWithDeviceCode(scopes, deviceCodeResult =>
{
Console.WriteLine(deviceCodeResult.Message); // Display login instructions
return Task.CompletedTask;
}).ExecuteAsync();
- AcquireTokenWithDeviceCode() initiates authentication using a device code.
- The
deviceCodeResult.Messageprovides instructions to the user on how to authenticate (typically directing them tohttps://microsoft.com/devicelogin). - Once the user completes authentication, the application receives an access token.
4. Retrieve and Display the Access Token
Console.WriteLine($"Access Token: {result.AccessToken}");
- The retrieved token can now be used to make API calls to Outlook Web Access services.
5. Handle Errors
catch (MsalException ex)
{
Console.WriteLine($"Authentication failed: {ex.Message}");
}
- MsalException handles authentication errors, such as incorrect permissions or expired tokens.
Running the Code
- Compile and run the program.
- Follow the login instructions displayed in the console.
- After signing in, the access token will be printed.
- Use the token in HTTP requests to Outlook Web Access APIs.
Conclusion
This code provides a straightforward way to obtain an access token for Outlook Web Access using a consumer account. The device code flow is particularly useful for command-line applications or scenarios where interactive authentication via a browser is required.
Cost-Effective SQL Server Database Restore on Microsoft #Azure: Using SMB Shares

1) Motivation Behind the Process
Managing costs efficiently on Microsoft Azure is a crucial aspect for many businesses, especially when it comes to managing resources like SQL Server databases. One area where I found significant savings was in the restoration of SQL Server databases.
Traditionally, to restore databases, I was using a managed disk. The restore process involved downloading a ZIP file, unzipping it to a .bak file, and then restoring it to the main OS disk. However, there was a significant issue with this setup: the cost of the managed disk.
Even when database restores happened only once every six months, I was still paying for the full capacity of the managed disk—500GB of provisioned space. This means I was paying for unused storage space for extended periods, which could be a significant waste of resources and money.
To tackle this issue, I switched to using Azure Storage Accounts with file shares (standard, not premium), which provided a more cost-effective approach. By restoring the database from an SMB share, I could pay only for the data usage, rather than paying for provisioned capacity on a managed disk. Additionally, I could delete the ZIP and BAK files after the restore process was complete, further optimizing storage costs.
2) Issues and Solutions
While the transition to using an Azure Storage Account for database restores was a great move in terms of cost reduction, it wasn’t without its challenges. One of the main hurdles I encountered during this process was SQLCMD reporting that the .bak file did not exist, even though it clearly did.
Symptoms of the Problem
The error message was:
3201, Level 16, State 2, Server [ServerName], Line 1
Cannot open backup device '\\<UNC Path>\Backups\GeneralPurpose.bak'. Operating system error 3(The system cannot find the path specified.)
Msg 3013, Level 16, State 1, Server [ServerName], Line 1
RESTORE DATABASE is terminating abnormally.
This was perplexing because I had confirmed that the .bak file existed at the UNC path and that the path was accessible from my system.
Diagnosis
To diagnose the issue, I started by enabling xp_cmdshell in SQL Server. This extended stored procedure allows the execution of operating system commands, which is very helpful for troubleshooting such scenarios.
First, I enabled xp_cmdshell by running the following commands:
-- Enable advanced options
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
-- Enable xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
Once xp_cmdshell was enabled, I ran a simple DIR command to verify if SQL Server could access the backup file share:
EXEC xp_cmdshell 'dir \\<UNC Path>\Backups\GeneralPurpose.bak';
The result indicated that the SQL Server service account did not have proper access to the SMB share, and that’s why it couldn’t find the .bak file.
Solution
To resolve this issue, I had to map the network share explicitly within SQL Server using the net use command, which allows SQL Server to authenticate to the SMB share.
Here’s the solution I implemented:
EXEC xp_cmdshell 'net use Z: \\<UNC Path> /user:localhost\<user> <PASSWORD>';
Explanation
- Mapping the Network Drive:
Thenet usecommand maps the SMB share to a local drive letter (in this case,Z:), which makes it accessible to SQL Server. - Authentication:
The/user:flag specifies the username and password needed to authenticate to the share. In my case, I used an account (e.g.,localhost\fsausse) with the correct credentials. - Accessing the Share:
After mapping the network drive, I could proceed to access the.bakfile located in the SMB share by using its mapped path (Z:). SQL Server would then be able to restore the database without the “file not found” error.
Once the restore was completed, I could remove the drive mapping with:
EXEC xp_cmdshell 'net use Z: /delete';
This approach ensured that SQL Server had the necessary permissions to access the file on the SMB share, and I could restore my database efficiently, only paying for the data usage on Azure Storage.
Conclusion
By transitioning from a managed disk to an SMB share on Azure Storage, I significantly reduced my costs during database restores. The issue with SQL Server not finding the .bak file was quickly diagnosed and resolved by enabling xp_cmdshell, mapping the network share, and ensuring proper authentication. This process allows me to restore databases in a more cost-effective manner, paying only for the data used during the restore, and avoiding unnecessary storage costs between restores.
For businesses looking to optimize Azure costs, this method provides an efficient, scalable solution for managing large database backups with minimal overhead.
#AWS #S3 Error – The request signature we calculated does not match the signature you provided. Check your key and signing method

If you’re working with the AWS SDK for .NET and encounter an error when uploading files to an Amazon S3 bucket, you’re not alone. A recent upgrade in the SDK may introduce unexpected behavior, leading to a “signature mismatch” error for uploads that previously worked smoothly. This blog post describes the problem, analyzes common solutions, and explains how AWS S3 pathing conventions have changed over time—impacting how we specify folders within S3 buckets.
The Problem: “The request signature we calculated does not match the signature you provided.”
When uploading a file to an Amazon S3 bucket using a .NET application, you may encounter this error:
“The request signature we calculated does not match the signature you provided. Check your key and signing method.”
The symptoms of this error can be puzzling. For example, a standard upload to the root of the bucket may succeed, but attempting to upload to a specific folder within the bucket could trigger the error. This was the case in a recent project, where an upload to the bucket carimagerydata succeeded, while uploads to carimagerydata/tx returned the signature mismatch error. The access key, secret key, and permissions were all configured correctly, but specifying the folder path still caused a failure.
Possible Solutions
When you encounter this issue, there are several things to investigate:
1. Bucket Region Configuration
Ensure that the AWS SDK is configured with the correct region for the S3 bucket. The SDK signs requests based on the region setting, and a mismatch between the region used in the code and the actual bucket region often results in signature errors.
csharpCopy codeAmazonS3Config config = new AmazonS3Config
{
RegionEndpoint = RegionEndpoint.YourBucketRegion // Ensure it's correct
};
2. Signature Version Settings
The AWS SDK uses Signature Version 4 by default, which is compatible with most regions and recommended by AWS. However, certain legacy setups or bucket configurations may expect Signature Version 2. Explicitly setting Signature Version 4 in the configuration can sometimes resolve these errors.
csharpCopy codeAmazonS3Config config = new AmazonS3Config
{
SignatureVersion = "4", // Explicitly specify Signature Version 4
RegionEndpoint = RegionEndpoint.YourBucketRegion
};
3. Permissions and Bucket Policies
Check if there are any bucket policies or IAM restrictions specific to the folder path you’re trying to upload to. If your bucket policy restricts access to certain paths, you’ll need to adjust it to allow uploads to the folder.
4. Path Style vs. Virtual-Hosted Style URL
Another possible issue arises from changes in how paths are handled. The AWS SDK has evolved over time, and the method of specifying paths within buckets has also changed. The SDK now defaults to virtual-hosted style URLs, where the bucket name is part of the domain (e.g., bucket-name.s3.amazonaws.com). Older setups, however, may expect path-style URLs, where the bucket name is part of the path (e.g., s3.amazonaws.com/bucket-name/key). Specifying path-style addressing in the configuration can sometimes fix compatibility issues:
csharpCopy codeAmazonS3Config config = new AmazonS3Config
{
UsePathStyle = true,
RegionEndpoint = RegionEndpoint.YourBucketRegion
};
Understanding the Key Change: Folder Path Format in S3
The reason these issues are so confusing is that AWS has changed the way folders (often called prefixes) are specified. Historically, users specified a bucket name combined with a folder path and then provided the object’s name. Now, however, the SDK expects a more unified format:
- Old Format:
bucket + path, object - New Format:
bucket, path + object
This means that in the new format, the folder path (e.g., /tx/) should be included as part of the object key rather than being treated as a separate parameter.
Solution: Specifying the Folder in the Object Key
To upload to a folder within a bucket, you should include the full path in the key itself. For example, if you want to upload yourfile.txt to the tx folder within carimagerydata, the key should be specified as "tx/yourfile.txt".
Here’s how to do it in C#:
csharpCopy codestring bucketName = "carimagerydata";
string keyName = "tx/yourfile.txt"; // Specify the folder in the key
string filePath = @"C:\path\to\your\file.txt";
AmazonS3Client client = new AmazonS3Client(accessKey, secretKey, RegionEndpoint.YourBucketRegion);
PutObjectRequest request = new PutObjectRequest
{
BucketName = bucketName,
Key = keyName, // Full path including folder
FilePath = filePath,
ContentType = "text/plain" // Example for text files, adjust as needed
};
PutObjectResponse response = await client.PutObjectAsync(request);
Conclusion
This error is a prime example of how changes in SDK conventions can impact legacy applications. The update to a more unified key format for specifying folder paths in S3 may seem minor, but it can cause unexpected issues if you’re unaware of it. By specifying the folder as part of the object key, you can avoid signature mismatch errors and ensure that your application is compatible with the latest AWS SDK practices.
Always remember to check SDK release notes for updates in configuration defaults, particularly when working with cloud services, as conventions and standards may change over time. This small adjustment can save a lot of time when troubleshooting!
Car License Plate #API support for #Lithuania

Introducing support for Lithuania via our Car License Plate API
Are you looking to seamlessly integrate detailed vehicle information into your applications? Welcome to Numerio Zenklai API, Lithuania’s latest and most advanced car license plate API. This service is designed to provide comprehensive vehicle details, enhancing your ability to offer top-tier services in the automotive, insurance, and related industries.
Why Choose Numerio Zenklai API?
Numerio Zenklai API offers a robust solution for retrieving detailed information about vehicles registered in Lithuania. With a simple request to the /CheckLithuania endpoint, you can obtain critical data, including the vehicle’s make, model, age, engine size, VIN, insurer, and a representative image.
Key Features
1. Comprehensive Vehicle Data:
Access a rich set of details about any Lithuanian-registered vehicle. For example, a query on the registration number “NAO075” returns the following data:
- Make and Model: Volkswagen Crafter
- Registration Year: 2006
- Engine Size: 2461 cc
- VIN: WV1ZZZ2EZE6017394
- Fuel Type: Diesel
- Insurance Company: ERGO INSURANCE SE LIETUVOS FILIALAS
- Vehicle Type: Lorry
- Body Type: Bus
- Representative Image: Image URL
2. Simple and Fast Integration:
Our API is designed for quick integration, ensuring you can start leveraging vehicle data with minimal setup. Here’s a sample JSON response for an easy understanding of the data format:
{
"Description": "VOLKSWAGEN CRAFTER",
"RegistrationYear": "2006",
"CarMake": {
"CurrentTextValue": "VOLKSWAGEN"
},
"CarModel": {
"CurrentTextValue": "CRAFTER"
},
"MakeDescription": {
"CurrentTextValue": "VOLKSWAGEN"
},
"ModelDescription": {
"CurrentTextValue": "CRAFTER"
},
"EngineSize": {
"CurrentTextValue": "2461"
},
"VIN": "WV1ZZZ2EZE6017394",
"FuelType": "Diesel",
"InsuranceCompany": "ERGO INSURANCE SE LIETUVOS FILIALAS",
"InsuranceCompanyNumber": "ACB 1798038:8192689",
"VehicleType": "LORRY",
"Body": "Bus",
"ImageUrl": "http://www.numeriozenklaiapi.lt/image.aspx/@Vk9MS1NXQUdFTiBDUkFGVEVS"
}
3. Reliable and Up-to-Date Information:
Our API ensures that you always receive the most current and accurate data directly from official sources, making it a reliable tool for various applications.
Use Cases
- Automotive Industry: Quickly verify vehicle details for sales, maintenance, and servicing.
- Insurance Companies: Validate vehicle information for underwriting and claims processing.
- Fleet Management: Monitor and manage a fleet of vehicles efficiently with detailed data.
- Law Enforcement: Access critical vehicle information swiftly for enforcement and regulatory purposes.
Getting Started
To begin using Numerio Zenklai API, visit our website and check out our comprehensive documentation. Our user-friendly interface and extensive support resources make it easy for developers to integrate the API into their existing systems.
Conclusion
Numerio Zenklai API is your go-to solution for accessing detailed vehicle information in Lithuania. Whether you’re in the automotive industry, insurance sector, or any field that requires precise vehicle data, our API provides the tools you need to enhance your services and streamline your operations.
Experience the power of reliable vehicle information with Numerio Zenklai API today. Visit Numerio Zenklai API to learn more and start integrating now!
Find #Azure Functions still using the in-process model in #Azure

If you got the following email from Microsoft Azure:
Migrate your .NET apps in Azure Functions to the isolated worker model by 10 November 2026
You’re receiving this email because you use the in-process model with .NET applications in Azure Functions.
Beginning 10 November 2026, the in-process model for .NET apps in Azure Functions will no longer be supported. To ensure that your apps that use this model continue being supported, you’ll need to transition to the isolated worker model by that date.
You may still use your .NET apps with the in-process model beyond 10 November 2026, but they will no longer receive security and feature updates from Microsoft.
The isolated worker model offers all the same functionality as the in-process model, plus improvements such as:
Full control of the dependency chain.
Isolation from platform lifecycle activities.
The ability to target Standard Term Support (STS) versions of .NET.
Required action
To ensure your .NET apps in Azure Functions continue to receive support, migrate to the isolated worker model by 10 November 2026.
Here is a script in both Powershell and Dos (Batch), to check which functions are using the in-process model; (Using the azure CLI for Windows)
This script logs into Azure, sets the subscription, lists the function apps, and checks the settings to identify which apps are using the in-process model for .NET:
powershellCopy code# Log in to Azure
az login
# Set your subscription (replace with your subscription ID)
$subscriptionId = "<your-subscription-id>"
az account set --subscription $subscriptionId
# List all function apps in the subscription
$functionApps = az functionapp list --query "[].{name:name, resourceGroup:resourceGroup}" --output tsv
Write-Output "Function Apps using in-process model for .NET:"
Write-Output "--------------------------------------------"
# Loop through each function app
$functionApps | ForEach-Object {
$name, $resourceGroup = $_ -split "`t"
# Get the app settings for the function app
$appSettings = az functionapp config appsettings list --name $name --resource-group $resourceGroup --query "[?name=='FUNCTIONS_WORKER_RUNTIME' || name=='FUNCTIONS_EXTENSION_VERSION']" | ConvertFrom-Json
# Check if the function app is using the in-process model
$isInProcess = $appSettings | Where-Object { $_.name -eq 'FUNCTIONS_WORKER_RUNTIME' -and $_.value -eq 'dotnet' }
if ($isInProcess) {
Write-Output "Function App Name: $name, Resource Group: $resourceGroup"
}
}
To run this script:
- Open PowerShell on your Windows machine.
- Copy and paste the script into the PowerShell window (or save it as a
.ps1file and run it). - Replace
<your-subscription-id>with your actual Azure subscription ID.
This script will list all function apps that are using the in-process model for .NET, helping you identify which ones need to be migrated to the isolated worker model.
If you prefer a DOS batch script, it’s a bit more complex due to the limitations of batch scripting, but here’s an attempt to do something similar using basic batch commands and PowerShell for processing:
batchCopy code@echo off
REM Log in to Azure (this will open a browser for authentication)
az login
REM Set your subscription (replace with your subscription ID)
set SUBSCRIPTION_ID=<your-subscription-id>
az account set --subscription %SUBSCRIPTION_ID%
REM List all function apps in the subscription and save to a temporary file
az functionapp list --query "[].{name:name, resourceGroup:resourceGroup}" --output tsv > functionapps.txt
echo Function Apps using in-process model for .NET:
echo --------------------------------------------
REM Loop through each function app
for /F "tokens=1,2" %%A in (functionapps.txt) do (
set NAME=%%A
set RESOURCE_GROUP=%%B
REM Get the app settings for the function app and save to a temporary file
az functionapp config appsettings list --name %NAME% --resource-group %RESOURCE_GROUP% --query "[?name=='FUNCTIONS_WORKER_RUNTIME' || name=='FUNCTIONS_EXTENSION_VERSION']" --output json > appsettings.json
REM Use PowerShell to check if the function app is using the in-process model
powershell -Command "
$appSettings = Get-Content 'appsettings.json' | ConvertFrom-Json;
$isInProcess = $appSettings | Where-Object { $_.name -eq 'FUNCTIONS_WORKER_RUNTIME' -and $_.value -eq 'dotnet' };
if ($isInProcess) { Write-Output 'Function App Name: %NAME%, Resource Group: %RESOURCE_GROUP%' }
"
)
REM Clean up temporary files
del functionapps.txt
del appsettings.json
To run this batch script:
- Open a text editor and copy the script into it.
- Save the file with a
.batextension, for example,checkFunctionApps.bat. - Run the batch file from the command prompt.
This script uses az commands to log in, set the subscription, and list the function apps. It then checks each app’s settings using PowerShell to determine if it is using the in-process model for .NET.