This page contains Windows bias

About This Page

This page is part of the Azure documentation. It contains code examples and configuration instructions for working with Azure services.

Bias Analysis

Bias Types:
⚠️ windows_first
⚠️ windows_tools
⚠️ powershell_heavy
⚠️ missing_linux_example
Summary:
The documentation demonstrates a Windows-first bias in several ways: instructions for setting environment variables and running commands are presented with Windows examples first and in more detail, references to Windows-specific tools (such as Notepad and Visual Studio) are made without equivalent Linux alternatives, and command-line instructions for running the sample application are described primarily in the context of Windows command prompts. While Linux equivalents are sometimes mentioned, they are often secondary and less detailed. There is also a lack of Linux-specific troubleshooting or tool recommendations, and no mention of Linux-native editors or shells beyond a brief 'export' example.
Recommendations:
  • Present Linux and Windows instructions in parallel, or alternate which comes first to avoid implicit prioritization.
  • Include Linux-native tool recommendations (e.g., gedit, nano, vim) alongside Notepad and Visual Studio.
  • Provide explicit instructions for running the sample application in Linux shells (e.g., bash, zsh), including how to set environment variables and execute dotnet commands.
  • Add troubleshooting tips for common Linux issues (e.g., file permissions, dependency installation).
  • Reference cross-platform editors (e.g., VS Code) more prominently and clarify that all steps can be performed on Linux.
  • Ensure screenshots and UI instructions are not Windows-centric, or provide Linux equivalents where possible.
  • Where Visual Studio is mentioned, also mention Visual Studio Code or JetBrains Rider as cross-platform alternatives.
GitHub Create pull request

Scan History

Date Scan ID Status Bias Status
2025-09-11 00:00 #108 completed ✅ Clean
2025-08-11 00:00 #77 completed ✅ Clean
2025-08-10 00:00 #76 completed ✅ Clean
2025-08-09 00:00 #75 completed ✅ Clean
2025-08-08 00:00 #74 completed ✅ Clean
2025-08-07 00:00 #73 completed ✅ Clean
2025-08-06 00:00 #72 completed ✅ Clean
2025-08-05 00:00 #71 completed ✅ Clean
2025-08-03 00:00 #69 completed ✅ Clean
2025-07-13 21:37 #48 completed ✅ Clean
2025-07-12 23:44 #41 in_progress ❌ Biased
2025-07-09 13:09 #3 cancelled ✅ Clean
2025-07-08 04:23 #2 cancelled ❌ Biased

Flagged Code Snippets

#### Update the routing endpoint resources When you export the Resource Manager template for a hub that has routing configured, you see that the keys for those resources aren't provided in the exported template. Their placement is denoted by asterisks. You must fill them in by going to those resources in the portal and retrieving the keys **before** you import the new hub's template and create the hub. If you moved the routing resources as well, update the name, ID, and resource group of each endpoint as well. * For endpoints with *key-based authentication*, retrieve the keys required for any of the routing resources and put them in the template. You can retrieve the key from each resource in the [Azure portal](https://portal.azure.com). * For endpoints with *identity-based authentication*: * Those that use a user-assigned managed identity have the **userAssignedIdentity** value populated with the identity ID information as a parameter. * Those that use a system-assigned managed identity can't be migrated. Delete these endpoints and their related routes from the template and make a note to recreate them in the new IoT hub. ## Create the new hub by loading the template Create the new hub using the edited template. If you have routing resources that are going to move, the resources should be set up in the new location and the references in the template updated to match. If you aren't moving the routing resources, they should be in the template with the updated keys. 1. Sign in to the [Azure portal](https://portal.azure.com). 1. Select **Create a resource**. 1. In the search box, search for and select **template deployment (deploy using custom templates)**. On the screen for the template deployment, select **Create**. 1. On the **Custom deployment** page, select **Build your own template in the editor**, which enables you to upload your template from a file. :::image type="content" source="./media/migrate-hub-arm/iot-hub-custom-deployment.png" alt-text="Screenshot showing the command for building your own template."::: 1. Select **Load file**. :::image type="content" source="./media/migrate-hub-arm/iot-hub-upload-file.png" alt-text="Screenshot showing the command for uploading a template file."::: 1. Browse for the new template you edited and select it, then select **Open**. It loads your template in the edit window. Select **Save**. :::image type="content" source="./media/migrate-hub-arm/iot-hub-uploaded-file.png" alt-text="Screenshot showing loading the template."::: 1. Fill in the following fields on the custom deployment page. **Subscription**: Select the subscription to use. **Resource group**: Select an existing resource group or create a new one. **Region**: If you selected an existing resource group, the region is filled in for you to match the location of the resource group. If you created a new resource group, this is its location. **Hub name**: Give the new hub a name. :::image type="content" source="./media/migrate-hub-arm/iot-hub-custom-deployment-create.png" alt-text="Screenshot showing the custom deployment page"::: 1. Select the **Review + create** button. 1. Select the **Create** button. The portal validates your template and deploys your new hub. If you have routing configuration data, it's included in the new hub, but points at the resources in the prior location. :::image type="content" source="./media/migrate-hub-arm/iot-hub-custom-deployment-final.png" alt-text="Screenshot showing the final custom deployment page"::: ## Manage the devices registered to the IoT hub Now that you have your new hub up and running, you need to copy all of the devices from the original hub to the new one. There are multiple ways to copy the devices. You either originally used [Device Provisioning Service (DPS)](../iot-dps/about-iot-dps.md) to provision the devices, or you didn't. If you did, this process isn't difficult. If you didn't, this process can be complicated. If you didn't use DPS to provision your devices, you can skip the next section and start with [Use Import/Export to move the devices to the new hub](#use-import-export-to-move-the-devices-to-the-new-hub). ## Use DPS to reprovision the devices in the new hub To use DPS to move the devices to the new location, see [How to reprovision devices](../iot-dps/how-to-reprovision.md). When you're finished, you can view the devices in the [Azure portal](https://portal.azure.com) and verify they are in the new location. Go to the new hub using the [Azure portal](https://portal.azure.com). Select your hub, then select **IoT Devices**. You see the devices that were reprovisioned to the new hub. You can also view the properties for the new hub. If you have implemented routing, test and make sure your messages are routed to the resources correctly. ### Roll back the changes after using DPS If you want to roll back the changes, reprovision the devices from the new hub to the old one. You're now finished migrating your hub and its devices. You can skip to [Clean-up](#clean-up). ## Use import-export to move the devices to the new hub The application targets .NET Core, so you can run it on either Windows or Linux. You can download the sample, retrieve your connection strings, set the flags for which bits you want to run, and run it. You can do this without ever opening the code. ### Download the sample Use the IoT C# SDK's [ImportExportDevicesSample](https://github.com/Azure/azure-iot-sdk-csharp/tree/main/iothub/service/samples/how%20to%20guides/ImportExportDevicesSample). Clone or download the repo to get the sample code. ### Options To run the application, specify three connection strings and five options. You pass this data in as command-line arguments or use environment variables, or use a combination of the two. We're going to pass the options in as command line arguments, and the connection strings as environment variables. The reason for this is because the connection strings are long and ungainly, and unlikely to change, but you might want to change the options and run the application more than once. To change the value of an environment variable, you have to close the command window and Visual Studio or Visual Studio Code, whichever you're using. Here are the five options you specify when you run the application: * **addDevices** (argument 1) - set this option to `True` if you want to add virtual devices that are generated for you. These devices are added to the source hub. Also, set **numToAdd** (argument 2) to specify how many devices you want to add. The maximum number of devices you can register to a hub is one million. The purpose of this option is for testing. You can generate a specific number of devices, and then copy them to another hub. * **copyDevices** (argument 3) - set this option to `True` to copy the devices from one hub to another. * **deleteSourceDevices** (argument 4) - set this option to `True` to delete all of the devices registered to the source hub. We recommend waiting until you're certain that all of the devices were transferred before you run this. Once you delete the devices, you can't get them back. * **deleteDestDevices** (argument 5) - set this option to `True` to delete all of the devices registered to the destination hub. You might want to do this if you want to copy the devices more than once. The basic command is *dotnet run*, which tells .NET to build the local csproj file and then run it. You add your command-line arguments to the end before you run it. Your command-line looks like these examples:
1. Right-click on the project *ImportExportDevicesSample* and select **Set as startup project**. 1. Set the variables at the top of Program.cs in the ImportExportDevicesSample folder for the five options.
### Use environment variables for the connection strings 1. To run the sample, you need the connection strings to the old and new IoT hubs, and to a storage account you can use for temporary work files. We'll store the values for these connection strings in environment variables. 1. To get the connection string values, sign in to the [Azure portal](https://portal.azure.com). 1. Put the connection strings somewhere you can retrieve them, such as NotePad. If you copy the following, you can paste the connection strings in directly where they go. Don't add spaces around the equal sign, or it changes the variable name. Also, you don't need double-quotes around the connection strings. If you put quotes around the storage account connection string, the script fails. Set the environment variables in Windows:
1. For the IoT hub connection strings, go to each hub in the portal. You can search in **Resources** for the hub. If you know the Resource Group, you can go to **Resource groups**, select your resource group, and then select the hub from the list of assets in that resource group. 1. Select **Shared access policies** from the Settings for the hub, then select **iothubowner** and copy one of the connection strings. Do the same for the destination hub. Add them to the appropriate SET commands. 1. For the storage account connection string, find the storage account in **Resources** or under its **Resource group** and open it. 1. Under the Settings section, select **Access keys** and copy one of the connection strings. Put the connection string in your text file for the appropriate SET command. Now you have the environment variables in a file with the SET commands, and you know what your command-line arguments are. Let's run the sample. ### Run the sample application and using command-line arguments 1. Open a command prompt window. Select Windows and type in `command prompt` to get the command prompt window. 1. Copy the commands that set the environment variables, one at a time, and paste them into the command prompt window and select Enter. When you're finished, type `SET` in the command prompt window to see your environment variables and their values. Once you've copied these into the command prompt window, you don't have to copy them again, unless you open a new command prompt window. 1. In the command prompt window, change directories until you are in ./ImportExportDevicesSample (where the ImportExportDevicesSample.csproj file exists). Then type the following, and include your command-line arguments.
### Run the sample application using Visual Studio 1. If you want to run the application in Visual Studio, change your current directory to the folder where the azureiot.sln file resides. Then run this command in the command prompt window to open the solution in Visual Studio. You must do this in the same command window where you set the environment variables, so those variables are known.