Saturday, December 21, 2024

Resolving Azure KeyVault Secrets in App Configuration

When working with Azure services, securely managing secrets is crucial. Azure Key Vault is a service designed to store and manage sensitive information like API keys, passwords, and certificates. Integrating Key Vault with your application configuration can streamline secret management and enhance security.

However, automatic resolution of Key Vault secrets in app configuration is only supported in Azure Functions and Azure App Service.

For other services, you need to manually resolve these secrets using a custom configuration builder.

In this blog, we’ll explore how to integrate Azure Key Vault with your .NET application configuration, ensuring that secrets are resolved securely and efficiently.

Automatic Resolution in Azure Functions and Azure App Service

In Azure Functions and Azure App Service, you can directly reference Key Vault secrets in your configuration files.
- For example:
```json
{
	"ApiManagement": {
    	"SubscriptionKey": "@Microsoft.KeyVault(VaultName=keyvaultName;SecretName=SecretKey)"
	}
}

```
This syntax allows the platform to automatically resolve the secret from Key Vault at runtime. Unfortunately, this automatic resolution is not available for other Azure services or on-premises applications.

Manual Resolution Using Configuration Builder

To resolve Key Vault secrets from .NET configuration in other services, you can extend the ConfigurationBuilder to fetch and replace secrets from Key Vault.

I’ll cover the following components:
1.**KeyVaultService**: A service to interact with Azure Key Vault.
2.**KeyVaultServiceFactory**: A factory to manage instances of KeyVaultService.
3.**ConfigurationBuilderExtensions**: An extension method to resolve Key Vault secrets in the configuration.
Required Packages:
1.**Azure.Identity**: This package provides the DefaultAzureCredential class used for authentication.
2.**Azure.Security.KeyVault.Secrets**: This package provides the SecretClient class used to interact with Azure Key Vault.
3.**Microsoft.Extensions.Configuration**: This package is used for configuration management.

```sh
dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Secrets
dotnet add package Microsoft.Extensions.Configuration
```
These packages are allowing you to use the **DefaultAzureCredential**, **SecretClient**, and **configuration management** features in your code.
KeyVaultService

The KeyVaultService class is responsible for interacting with Azure Key Vault to retrieve secrets. It uses the SecretClient from the Azure SDK and handles authentication using **DefaultAzureCredential**.

```csharp
using Azure;
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
///<summary>
/// A service that fetches secrets from Azure Key Vault.
///</summary>
internal sealed class KeyVaultService:IKeyVaultService
{
    private readonly SecretClient _secretClient;

    ///<summary>
    /// Initializes a new instance of the  class.
    ///</summary>
    ///<param name="vaultName">The name of the Azure Key Vault.
    internal KeyVaultService(string vaultName)
    {
        ArgumentException.ThrowIfNullOrEmpty(vaultName, nameof(vaultName));
        try
        {
            var keyVaultEndpoint = new Uri($"https://{vaultName}.vault.azure.net/");
            _secretClient = new SecretClient(keyVaultEndpoint, new DefaultAzureCredential());
        }
        catch (UriFormatException ex)
        {
            throw new ArgumentException($"Invalid Azure Key Vault name '{vaultName}'.", ex);
        }
        catch (AuthenticationFailedException ex)
        {
            throw new UnauthorizedAccessException($"Failed to authenticate with Azure Key Vault '{vaultName}'. Please check your credentials and environment configuration.", ex);
        }
    }

    ///<summary>
    ///Fetches the secret value from Azure Key Vault.
    ///</summary>
    ///<param name="secretName">The name of the secret in the Azure Key Vault.
    ///<returns>
      string IKeyVaultService.GetSecret(string secretName)
    {
        ArgumentException.ThrowIfNullOrEmpty(secretName, nameof(secretName));
        try
        {
            Response secretResponse = _secretClient.GetSecret(secretName);

        if (secretResponse == null || secretResponse.Value == null)
        {
            throw new InvalidOperationException($"Secret '{secretName}' not found in Key Vault.");
        }

        KeyVaultSecret secret = secretResponse.Value;

        if (secret.Value == null)
        {
            throw new InvalidOperationException($"Secret '{secretName}' has no value.");
        }

        return secret.Value;
        }
        catch (RequestFailedException ex) when (ex.Status == 404)
        {
            throw new KeyNotFoundException($"Secret '{secretName}' not found in Key Vault.", ex);
        }
        catch (RequestFailedException ex) when (ex.Status == 403)
        {
            throw new UnauthorizedAccessException($"Access to secret '{secretName}' is forbidden. It might be expired or you might not have the necessary permissions.", ex);
        }
    }
}

///<summary>
/// Interface for a service that fetches secrets from Azure Key Vault.
///</summary>
internal interface IKeyVaultService
{
    ///<summary>
    /// Fetches the secret value from Azure Key Vault.
    ///</summary>
    ///<param name="secretName">The name of the secret in the Azure Key Vault.
    ///<returns>The secret value.
    internal string GetSecret(string secretName);
}
```
KeyVaultServiceFactory

The KeyVaultServiceFactory class manages instances of KeyVaultService for different vault names. It ensures that each KeyVaultService is created only once per vault name and reused for subsequent requests.

```csharp
///<summary>
/// A factory that creates or retrieves instances of the  class.
//</summary>
internal static class KeyVaultServiceFactory
{
    private static readonly Dictionary<string, IKeyVaultService> keyVaultServices = [];

    ///<summary>
    /// Gets or creates an instance of the <see cref="KeyVaultService"/> class for the specified Azure Key Vault.
    ///</summary>
    ///<param name="vaultName">
    ///<returns>
    internal static IKeyVaultService GetOrCreateKeyVaultService(string vaultName)
    {
        ArgumentException.ThrowIfNullOrEmpty(vaultName, nameof(vaultName));

        if (!keyVaultServices.TryGetValue(vaultName, out var keyVaultService))
        {
            keyVaultService = new KeyVaultService(vaultName);
            keyVaultServices[vaultName] = keyVaultService;
        }

        return keyVaultService;
    }
}
```
ConfigurationBuilderExtensions

The ConfigurationBuilderExtensions class contains an extension method to resolve Key Vault secrets in the configuration. It uses the KeyVaultServiceFactory to get or create KeyVaultService instances and fetch secrets.
```csharp
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Text.RegularExpressions;

/// <summary>
/// Extension methods for <see cref="IConfigurationBuilder"/> to resolve and update configuration values from Azure Key Vault.
/// </summary>
internal static partial class ConfigurationBuilderExtensions
{
    /// <summary>
    /// Resolves and updates configuration values that use the special syntax for Azure Key Vault secrets.
    ///</summary>
    ///<param name="builder">The  to add the resolved configuration values to.
    ///<returns>The  with the resolved configuration values.
    internal static IConfigurationRoot ResolveKeyVaultSecrets(this IConfigurationBuilder builder)
    {
        var configuration = builder.Build();
        var resolvedKeyValuePairs = new List<KeyValuePair>();

        foreach (var configItem in configuration.AsEnumerable())
        {
            if (!string.IsNullOrEmpty(configItem.Value))
            {
                var vaultSecretMatch = KeyVaultRegex().Match(configItem.Value);
                if (vaultSecretMatch.Success)
                {
                    var vaultName = vaultSecretMatch.Groups["vault"].Value;
                    var secretName = vaultSecretMatch.Groups["secret"].Value;

                    IKeyVaultService keyVaultService = KeyVaultServiceFactory.GetOrCreateKeyVaultService(vaultName);

                    // Collect the resolved key-value pair
                    resolvedKeyValuePairs.Add(new KeyValuePair<string, string?>(configItem.Key, keyVaultService.GetSecret(secretName)));
                }
            }
        }
        // Update the configuration with the resolved key-value pairs if any
        if (resolvedKeyValuePairs.Any())
        {
            _ = builder.AddInMemoryCollection(resolvedKeyValuePairs);
        }
        return configuration;
    }

    ///<summary>
    /// Returns a regular expression that matches the special syntax for Azure Key Vault secrets.
    /// </summary>
    /// <returns>
    private static Regex KeyVaultRegex() => new(@"@Microsoft\.KeyVault\(VaultName=(?<vault>[^;]+);SecretName=(?[^\)]+)\)");
}

```
Explanation
1.**Regex Pattern**: The KeyVaultRegex method defines a regular expression to match the Key Vault reference pattern in the configuration values.
2.**Configuration Parsing**: The ResolveKeyVaultSecrets method iterates through the configuration items, identifies Key Vault references, and fetches the corresponding secrets.
3.**Secret Retrieval**: The GetSecret method uses the SecretClient from the Azure SDK to fetch the secret value from Key Vault.
4.**Configuration Update**: The resolved secrets are added back to the configuration using an in-memory collection.
Usage

To use this extension method, simply call it on your ConfigurationBuilder instance:

```csharp
var configuration = new ConfigurationBuilder()
                   	.SetBasePath(Directory.GetCurrentDirectory())
	                .AddJsonFile("appsettings.json")
	                .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
	                .AddEnvironmentVariables()
	                .ResolveKeyVaultSecrets();
```
Summary

By following this approach, you can securely manage and resolve Azure Key Vault secrets from Configuration in your .NET applications. The KeyVaultService handles interaction with Key Vault, the KeyVaultServiceFactory manages KeyVaultService instances, and the ConfigurationBuilderExtensions integrates secret resolution into your configuration setup.

This ensures that your application can securely access secrets, regardless of the hosting environment and maintain flexibility and security across different services and deployment scenarios.

Sunday, November 19, 2023

How to install winget utility using powershell

Windows Package Manager (winget) is a command-line tool that enables users to discoer, install, upgrade, remove and configure application on windows 10 and higher version We can install winget utility using below powershell script in windows

```sh
$progressPreference = 'silentlyContinue'

Write-Information "Downloading WinGet and its dependencies..."

Invoke-WebRequest -Uri https://aka.ms/getwinget -OutFile Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle

Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -OutFile Microsoft.VCLibs.x64.14.00.Desktop.appx

Invoke-WebRequest -Uri https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.7.3/Microsoft.UI.Xaml.2.7.x64.appx -OutFile Microsoft.UI.Xaml.2.7.x64.appx

Add-AppxPackage Microsoft.VCLibs.x64.14.00.Desktop.appx

Add-AppxPackage Microsoft.UI.Xaml.2.7.x64.appx

Add-AppxPackage Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle

```

Below is code snippet to install Net 7.0 SDK using winget 

```sh
winget install Microsoft.DotNet.SDK.7
```

Below is code snippet to install Net 7.0 runtime  using winget 
```sh
winget install dotnet-runtime-7
```powershell

Sunday, October 8, 2023

Get Folders with Exclude folders recursively

In general , we can use get-childitems to get folders recursively and if we want to exculde any list of folders then we can use Exclude switch but this switch wont work for recursively , it only work for current depth so we can use below recursive function to get list of folders recursively by excluding list of folders recursively.

```sh 
function Get-Folders {
    param (
        [string]$Path,
        [string[]]$Excludes
    )
     $list = New-Object System.Collections.Generic.List[string]
    $Directories=(gci $path -Directory -Exclude $Excludes ).FullName

    foreach ( $Directory in $Directories)
    {
      $Directory
      Get-Folders $Directory -Excludes $Excludes
    }
}

[string[]]$Excludes=@("bin","obj",".vscode","dialogs","Controllers","AzureOpenAIBot")

Get-Folders "C:\Users\codeRep\labs\aztd-OpenAI"  -Excludes $Excludes
```

Monday, September 18, 2023

git stash usages

----
Sure, here are some examples of how you gcan use `git stash`:

1. **Save changes to a new stash**:
   
   - Suppose you're working on a new feature in a dedicated branch, but you need to switch to another branch to fix a bug.
   - You've made changes that you don't want to commit yet, so you can stash them. Here's how you can do it:

   ```bash
   git stash save "WIP on new feature"
   ```

   This command will save your changes to a new stash with the message "WIP on new feature". You can use any message that helps you remember what changes are in the stash.

2. **List all stashes**:
   - If you want to see all of the stashes that you've currently saved, you can use this command:

   ```bash
   git stash list
   ```

   This command will show you a list of all stashes that you currently have.

3. **Apply changes from the most recent stash**:
  - Once you're ready to continue working on your new feature, you can apply the changes from your most recent stash using this command:

   ```bash
   git stash pop
   ```

   This command will apply the changes from the most recent stash and then remove it from your list of stashes.

4. **Apply changes from a specific stash**:
  -  If you have multiple stashes and you want to apply changes from a specific one, you can do so with this command:

   ```bash
   git stash apply stash@{10}
   ```

   This command will apply the changes from the stash named `stash@{10}`.

5. **Discard the most recent stash**:
   - If you decide that you no longer need the changes in your most recent stash, you can discard it with this command:

   ```bash
   git stash drop
   ```

   This command will discard the most recent stash.

6. **Remove all stashes**:
   - If you want to remove all of your stashes at once, you can use this command:

   ```bash
   git stash clear
   ```

   This command will remove all of your stashes.

Note Remember, any changes that are stashed are kept locally and are not transferred when you push your commits to a remote repository.

Sunday, September 17, 2023

Ways of Identifying duplicate rows in SQL

----

To find duplicate rows using partition and rank, you can use the following steps:

- First, you need to use the PARTITION BY clause to divide the rows in your table into groups based on one or more columns that you want to compare for duplicates. For example, if you want to find duplicate rows based on the name and address columns, you can use PARTITION BY name, address.

- Next, you need to use the ORDER BY clause to specify the order of rows within each partition. You can use any column that you want to sort by, such as the ID column. For example, you can use ORDER BY ID.

- Then, you need to use the RANK () function to assign a rank to each row within each partition. The rank starts from 1 and increases by 1 for each row. If two or more rows have the same values in the partition columns, they will have the same rank. For example, you can use RANK () OVER (PARTITION BY name, address ORDER BY ID) AS rank.

- Finally, you need to select the rows that have a rank greater than 1. These are the duplicate rows that have the same values in the partition columns as another row. You can use a subquery or a common table expression (CTE) to filter these rows. For example, you can use:

```sql
-- Using a subquery

SELECT * FROM (
  SELECT *, RANK () OVER (PARTITION BY name, address ORDER BY ID) AS rank
  FROM table_name
) t
WHERE rank > 1;

-- Using a CTE

WITH cte AS (
  SELECT *, RANK () OVER (PARTITION BY name, address ORDER BY ID) AS rank
  FROM table_name
)

SELECT * FROM cte WHERE rank > 1;

```

There are some other ways to find duplicate rows in SQL, depending on the database system and the requirements. Here are some examples:

- You can use the EXISTS or NOT EXISTS operator to check if a row exists in a subquery that matches the values of another row. For example, you can use this query to find duplicate rows based on the name and address columns:

```sql
SELECT * FROM table_name t1 
WHERE EXISTS (
  SELECT 1 FROM table_name t2
  WHERE t1.name = t2.name
  	AND t1.address = t2.address
  	AND t1.id <> t2.id
);

```

- You can use the JOIN clause to join a table with itself and compare the values of the columns. For example, you can use this query to find duplicate rows based on the name and address columns:


```sql
SELECT t1.* FROM table_name t1
JOIN table_name t2
	ON t1.name = t2.name
	AND t1.address = t2.address
	AND t1.id <> t2.id;
```

- You can use the DISTINCT or GROUP BY clause to select only the unique values of the columns and then use the EXCEPT or MINUS operator to subtract them from the original table. For example, you can use this query to find duplicate rows based on the name and address columns:

```sql
SELECT name, address FROM table_name

EXCEPT

SELECT DISTINCT name, address FROM table_name;
```

To identify duplicate rows using group by in SQL, you can use the following steps:

- First, you need to select the columns that you want to check for duplicates using the SELECT statement. For example, if you want to find duplicate rows based on the name and address columns, you can use SELECT name, address.
- Next, you need to use the GROUP BY clause to group the rows by the selected columns. For example, you can use GROUP BY name, address.
- Then, you need to use the COUNT function in the HAVING clause to filter the groups that have more than one row. These are the groups that contain duplicates. For example, you can use HAVING COUNT (*) > 1.
- Finally, you need to execute the query and see the results. For example, the complete query would look like this:

```sql
SELECT name, address FROM table_name 
	GROUP BY name, address 
	HAVING COUNT (*) > 1;
```

This query will return all the rows that have duplicate values in the name and address columns.


Remove port in windows

----

To remove a port in Windows, you need to find and kill the process that is using that port. You can do that by following these steps:

- Open a command prompt as an administrator.
- Type the command `netstat -ano | findstr :8000` and press Enter. This will show you the process ID (PID) of the process that is using port 8000.
- Type the command `taskkill /F /PID ` and press Enter, where `` is the number you found in the previous step. This will force the process to terminate and free the port.
- You can verify that the port is no longer in use by typing the command `netstat -ano | findstr :8000` again and seeing no results.

```sh
	netstat -ano | findstr :8000
	taskkill /F /PID  8992  #  example PID 8992 which was return by above statement
```


Wednesday, September 13, 2023

Extract SQL query from Open Database connection in EXCEL

----
1. This script opens an Excel file, loops through each connection in the workbook, checks if the connection is an OLEDB connection,
2. then prints the command text (SQL query) of each OLEDB connection.
3. Rplace "C:\path\to\your\Spreadshee.xlsx" with the path to your Excel file1.

```sh
# Create an Excel COM object
$excel = New-Object -ComObject Excel.Application
Extracting SQL queries from Excel’s open data connection

# Open the workbook
$workbook = $excel.Workbooks.Open("C:\path\to\your\Spreadshee.xlsx")

# Loop through each connection in the workbook
foreach ($connection in $workbook.connections) {
    # Check if the connection is an OLEDB connection
    if ($connection.Type -eq 2) {
        # Get the OLEDB connection
        $oledbConnection = $connection.OLEDBConnection

        # Print the command text (SQL query)
        Write-Output $oledbConnection.CommandText
    }
}

# Close the workbook and quit Excel
$workbook.Close()
$excel.Quit()

# Release the COM objects
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($workbook) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel) | Out-Null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

```
Please note that this script requires Excel to be installed on your machine, as it uses Excel’s COM object model.
Also, running scripts that use COM objects might have issues with non-interactive sessions (like a scheduled task or a remote session).

Extract Data from Excel using powershell

----

1. This script opens an Excel file and reads data from a sheet named Sheet. 

2. Replace "SELECT * FROM [Sheet1$]" with the query that suits your needs.

3. Also, please ensure that the Microsoft.ACE.OLEDB.12.0 provider is installed on your machine, as it’s required to read data from Excel1.


```sh

#Read data from Excel
$cnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='Excel 12.0;HDR=YES';Data Source=c:temptest.xlsx;Mode=Share Deny Write;Jet OLEDB:Engine Type=37;"
$cn = New-Object System.Data.OleDb.OleDbConnection $cnStr
$cn.Open()
$cmd = $cn.CreateCommand()
$cmd.CommandText = "SELECT * FROM [Sheet1$]"
$rdr = $cmd.ExecuteReader()
$dt = new-object System.Data.DataTable
$dt.Load($rdr)
$dt | Out-GridView


```
Please note that this script reads data from Excel using SQL,but it doesn’t extract SQL queries stored in Excel. 
If you have SQL queries stored in cells of an Excel sheet and you want to extract them, you would need to adjust the script to select those specific cells.

Saturday, September 9, 2023

Get Team chat details using Microsoft.Graph

----
1. Install-Module Microsoft.Graph
2. Connect MicrosoftGraph API  Module
3. Get chat id using Get-MgChat commandlet
4. Get Chat member for particular chat id using Get-MgChatMember
5. Get chat messages\Chat history for particular chat using Get-MgChatMessage
```sh
Install-Module Microsoft.Graph
Import-Module Microsoft.Graph

Connect-MgGraph

<# "Get-MgChat" ,"Get-MgChatMember","Get-MgChatMessage" | 
& {Process{Find-mggraphcommand Get-MgChat|select permissions|
&{Process{Connect-MgGraph -Scopes $_}} }} #>

$displayName="< Display Name>"
$user=Get-MgUser  -Filter "DisplayName eq '$displayName'"

Get-MgChat  | select Topic,ChatType,id,WebUrl

$chatID=$(Get-MgChat  | select id -First 1).id


#Get all Chat members for chat 
Get-MgChatMember -ChatId $chatID | select AdditionalProperties).AdditionalProperties

#Get ACS chat members
(Get-MgChatMember -ChatId $chatID |Where DisplayName -eq raz| select AdditionalProperties).AdditionalProperties

#Get AAD chat members
(Get-MgChatMember -ChatId $chatID |Where DisplayName -eq 'razesh'| select AdditionalProperties).AdditionalProperties

#Get chat messages for chat id

Get-MgChatMessage -ChatId $chatID |& {Process{ if ($($_.From.User.DisplayName)) {Write-host "From :$($_.From.User.DisplayName)" ;"Message:$($_.body.Content)";  Write-Host ""}}}

```

Invoke Microsoft Graph API endpoint using accesstoken in az cli


----

To get an access token for Graph API call, you can follow the steps below:


Go to the Azure portal and sign in to your account.
Navigate to the Azure Active Directory resource that you want to use.
1. Click on the App registrations tab.
2. Select the app that you want to use.
3. Click on the Certificates and  secrets tab.
4. Click on the New client secret button.
5. Enter a description for the client secret and select an expiration date.
6. Click on the Add button.
7. Copy the value of the client secret and store it securely.
8  Use the copied client secret value to authenticate your requests.
9. You can use the following code snippet in PowerShell to get an access token:


```sh
$tenantId = "< your-tenant-id >"
$appId = "<your-app-id >"
$clientSecret = "< your-client-secret >"
$resource = "https://graph.microsoft.com"
$body = @{grant_type="client_credentials";client_id="$appId";client_secret="$clientSecret";resource="$resource"}
$oauthUrl = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$oauth = Invoke-RestMethod -Method Post -Uri $oauthUrl -Body $body
$accessToken = $oauth.access_token

# Note: Replace < your-tenant-id >, < your-app-id >, and < your-client-secret  > with your own values.
```

----

Example 1: 


```sh
$tenantId = "< your-tenant-id >"
$appId = "<your-app-id >"
$clientSecret = "< your-client-secret >"
$resource = "https://graph.microsoft.com"
$body = @{grant_type="client_credentials";client_id="$appId";client_secret="$clientSecret";resource="$resource"}
$oauthUrl = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$oauth = Invoke-RestMethod -Method Post -Uri $oauthUrl -Body $body
$accessToken = $oauth.access_token

$headers = @{
    "Authorization" = "Bearer $accessToken"
}
$response=Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users" -Headers $headers 
$response.value  | select id , displayname

# Note: Replace < your-tenant-id >, < your-app-id >, and < your-client-secret  > with your own values.
# Note: Need User.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All Permissions to access MS graph users API endpoint
```


Example 2:

```sh
$tenantId = "< your-tenant-id >"
$appId = "<your-app-id >"
$clientSecret = "< your-client-secret >"
$resource = "https://graph.microsoft.com"
$body = @{grant_type="client_credentials";client_id="$appId";client_secret="$clientSecret";resource="$resource"}
$oauthUrl = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$oauth = Invoke-RestMethod -Method Post -Uri $oauthUrl -Body $body
$accessToken = $oauth.access_token

$headers = @{
    "Authorization" = "Bearer $accessToken"
}
$response=Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/users" -Headers $headers 
$response. value  | select id , displayname

(Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/groups?$filter=resourceProvisioningOptions/Any (x:x eq 'Team')" -Headers $headers).value |select id , displayname , mailNickName , mail


# Note: Replace < your-tenant-id >, < your-app-id >, and < your-client-secret  > with your own values.
# Note: Need 	Group.Read.All, Group.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All  Permissions to access MS graph groups API endpoint

```



Example 3:

```sh
$tenantId = "< your-tenant-id >"
$appId = "<your-app-id >"
$clientSecret = "< your-client-secret >"
$displayName ="< displayName>"
$resource = "https://graph.microsoft.com"
$body = @{grant_type="client_credentials";client_id="$appId";client_secret="$clientSecret";resource="$resource"}
$oauthUrl = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$oauth = Invoke-RestMethod -Method Post -Uri $oauthUrl -Body $body
$accessToken = $oauth.access_token

$headers = @{
    "Authorization" = "Bearer $accessToken"
     "Content-Type"  = "application/json"
}

$filter='$filter'
$uri = "https://graph.microsoft.com/v1.0/users?$filter=displayName eq '$displayName' "
$response=Invoke-RestMethod -Uri $uri -Headers $headers 
$response. value  | select id , displayname

# Note: Replace < your-tenant-id >, < your-app-id >, and < your-client-secret  > with your own values.
# Note: Need User.Read.All, User.ReadWrite.All, Directory.Read.All, Directory.ReadWrite.All Permissions to access MS graph users API endpoint

```

How to invoke Azure Management API with Access token using AZ CLI


#### list of steps to invoke Azure Management API with Azure access token using AZ CLI.

1. log into Azure  using Az CLI 
2. Get access token using account get-access-token 
3. add bearer accesstoken as authorization Header
4. Invoke Azure Managment API 

```sh

az login
$subId=(az account list --query "[?isDefault].id" )|ConvertFrom-Json
$accesstoken =  [string](az account get-access-token | ConvertFrom-Json).accessToken
$headers = @{ Authorization = "Bearer $accesstoken" }
$url="< Azure Management API >"
$r= Invoke-WebRequest  -Uri  $url -Headers $headers
If ($r.StatusCode -eq 200 ) {($r.Content |ConvertFrom-Json).value}

# Replace  < Azure Management API > with your values  
```

Example: 

```sh
az login
$subId=(az account list --query "[?isDefault].id" )|ConvertFrom-Json
$accesstoken =  [string](az account get-access-token | ConvertFrom-Json).accessToken
$headers = @{ Authorization = "Bearer $accesstoken" }
$url="https://management.azure.com/subscriptions/$subId/providers/Microsoft.Compute/locations/eastus/runCommands?api-version=2022-11-01"
$r= Invoke-WebRequest  -Uri  $url -Headers $headers
If ($r.StatusCode -eq 200 ) {($r.Content |ConvertFrom-Json).value}
```
________


App Registration in Azure

----

#### Register App using AZ Cli 

1. Login into azure using az cli 
2. Create azure active directory service principle usign AZ CLI

```sh

$AppName="<AppName >"
az login
$subId=az account list --query "[?isDefault].id" | ConvertFrom-Json
az account set --subscription $subid
az ad sp create-for-rbac -n $AppName
```
-----

#### Register App using AZ Portal



1. Go to the Azure portal and sign in to your account.
2. Navigate to the Azure Active Directory resource that you want to use.
3. Click on the App registrations tab and click on New registration
4. Enter User-facing Display name  and click on Register

Saturday, September 2, 2023

Create Azure Communication identity and token using az cli


### Add the Azure Communication Services extension for Azure CLI by using the az extension command.

1. Add communication extension in az cli  (one time activity)
2. Connect to Azure using Az Cli
3. Create Identity using az communication user-identity 
4. Issue Identity Token for specific scope (voip, chat)


```sh 
az extension add --name communication
$acsName="< acs-Name >"
$resouceGroup="< Resource Group Name >"

$connection=az communication list-key --name $acsName --resource-group $resouceGroup  --query "primaryConnectionString"

$rawId=az communication user-identity user create --connection-string $connection  --query "rawId"

az communication identity token issue --scope chat voip  --user $rawId --connection-string $connection  --query "token"


Note:

#$rawId=az communication identity user create --connection-string $connection  --query "rawId"

#This command is implicitly deprecated because command group 'communication identity token' is deprecated and will be removed in a future release. Use communication user-identity token' instead.
```
___

Example :

```sh 

az extension add --name communication

az login

$acsName="aztds-acs-poc0821"

$resouceGroup="rg-aztds-acs-poc"

$connection=az communication list-key --name $acsName --resource-group $resouceGroup  --query "primaryConnectionString"

$rawId=az communication user-identity user create --connection-string $connection  --query "rawId"

az communication identity token issue --scope chat voip  --user $rawId --connection-string $connection  --query "token"

```

Get Teams User's Availability using Microsoft Graph API


Get Teams User's Availability using Microsoft Graph API through Invoke-RestMethod 


```sh
# Import the required modules

Install-Module -Name AzureAD
Install-Module MicrosoftTeams


Import-Module AzureAD
Import-Module MicrosoftTeams

	# Connect to Azure AD
Connect-AzureAD

	# Get an access token for the Graph API
$accessToken = (Get-AzureADToken -Resource "https://graph.microsoft.com").AccessToken

	# Set the Graph API endpoint URL
$graphApiUrl = "https://graph.microsoft.com/v1.0/users//presence"

	# Set the headers for the request
$headers = @{
    "Authorization" = "Bearer $accessToken"
}

	# Send the request to the Graph API and get the response
$response = Invoke-RestMethod -Method Get -Uri $graphApiUrl -Headers $headers

	# Output the presence status of the user
$response.availability
```

Get Teams User id using Microsoft Grapth API


Get Teams User id using Microsoft Grapth API

```sh
Install-Module Microsoft.Graph

# Import the required module
Import-Module Microsoft.Graph

# Connect to Microsoft Graph
Connect-MgGraph

# Get the user object for the specified user
$user = Get-MgUser -Filter "mail eq '[email protected]'"

# Output the user ID
$user.Id

```

Post message using Microsoft Graph powershell moduel

Post message using Microsoft Graph powershell moduel <\i>


```sh
Install-Module Microsoft.Graph -Scope CurrentUser
Install-Module Microsoft.Graph.Beta


Import-Module Microsoft.Graph -Scope CurrentUser

# Connect to MgGraph

Connect-MgGraph


Find-MgGraphCommand -command Get-MgUser | Select -First 1 -ExpandProperty Permissions

#Grant permission

Connect-MgGraph -Scopes "User.Read.All","Group.ReadWrite.All"

$user = Get-MgUser -Filter "displayName eq 'Raj'"

# Get Teams for user 
Get-MgUserJoinedTeam -UserId $user.Id

# Get Teams for user 

$TeamId=$(Get-MgUserJoinedTeam -UserId $user.Id).ID
$team = Get-MgTeam -TeamId $TeamId

# Get Team channel  for specific Team

$channel = Get-MgTeamChannel -TeamId $team.Id -Filter "displayName eq 'General'"

# Post message in specific Team channel
New-MgTeamChannelMessage -TeamId $team.Id -ChannelId $channel.Id -Body @{ Content="Hello Teams"} 

# Post message in specific Team channel
New-MgTeamChannelMessage -TeamId $team.Id -ChannelId $channel.Id -Body @{ Content="Hello World" } -Importance "urgent"

# DisConnect to MgGraph
Disconnect-MgGraph
 
```

clone git repository with specific branch only

clone git repository with specific branch only

```sh
#syntax

git clone --single-branch --branch <branch-name >  git-url

#example
git clone --single-branch --branch master https://github.com/career-tutorials/ck.git --progress

```

Re install NPM Packages

Reinstall all NPM Packages

 Remove modules under node_modules on Linux or Mac OS 
```sh
rm -rf node_modules && npm install
```

 Remove modules under node_modules on Windows 
```sh
del /s /q node_modules && npm install
```

 Clean  modules from cache , rebuild  and install packages 
```sh 
npm cache clean --force
npm rebuild
npm install

```
 The npm audit fix command will install any packages that are missing in node_modules but it’s present in package.json 

```sh
 npm audit fix
```

 npm update will update any packages that are present in the project.

```sh
npm update

#so we can run this to reinstall any packages that are missing.

```

Availability of Teams user using Microsoft.Graph and Microsoft.Graph.CloudCommunications communication module

Availability of Teams user using Microsoft.Graph and Microsoft.Graph.CloudCommunications Poweshell module

```sh
#Install Module 
Install-Module Microsoft.Graph -Scope CurrentUser
Install-Module Microsoft.Graph.CloudCommunications

#Import Module 
Import-Module Microsoft.Graph
Import-Module Microsoft.Graph.CloudCommunications

# Connect to Microsoft Graph

Connect-MgGraph

# Fina required permission for Get-MgCommunicationPresenceByUserId

Find-MgGraphCommand -command Get-MgCommunicationPresenceByUserId  | Select -First 1 -ExpandProperty Permissions

# Grant scope of access 
Connect-MgGraph -Scopes "Presence.Read.All","Presence.Read"

# get user details using  Microsoft Graph
$user1 = Get-MgUser -Filter "displayName eq 'Rajesh'"
$user2 = Get-MgUser -All | Where-Object {$_.DisplayName -like "*Mark*"}
$params = @{
			ids = @(
                  $user1.Id
                  $user2.Id
				)
		}


# Get Presence  by user id 
#Get-MgCommunicationPresenceByUserId -BodyParameter $params


# Get Presence by user id for Availability other than offline ,DoNotDisturb ,BeRightBack, Away

Get-MgCommunicationPresenceByUserId -BodyParameter $params | where Availability  -NotIn 'Offline','DoNotDisturb','BeRightBack','Away'

# Get Presence by user id who are available 

Get-MgCommunicationPresenceByUserId -BodyParameter $params | where Availability  -EQ 'Available'


#There is other way Get Presence for user id
 
 Get-MgUserPresence -UserId $user1.Id


```

Wednesday, August 30, 2023

Performance of process, CPU Utilization and Memory Utilization for specific system

Performance of each process in the machine

```sh
	$servername ="Machine1" # update Machine \hostname
	gwmi Win32_PerfFormattedData_PerfProc_Process -filter "Name <> '_Total' and Name <> 'Idle'" -Computer $servername | 
    where { $_.PercentProcessorTime -gt 0 } | 
    select PSComputerName, Name, PercentProcessorTime | 
    sort PercentProcessorTime -Descending
```
CPU Utilization

```sh
		$serverName ="Machine1"  # update Machine \hostname
		$ProcessorTime = (Get-WmiObject -ComputerName $serverName -Class win32_processor -ErrorAction Stop |
        	Measure-Object -Property LoadPercentage -Average | 
            Select-Object Average).Average
		$ProcessorTime
```
Memory Utilization

```sh
	$serverName ="Machine1"  # update Machine \hostname
	$ComputerMemory = Get-WmiObject -ComputerName $ServerName -Class win32_operatingsystem -ErrorAction Stop;
	$MemoryUtilization  = ((($ComputerMemory.TotalVisibleMemorySize - $ComputerMemory.FreePhysicalMemory)*100)/ $ComputerMemory.TotalVisibleMemorySize); $RoundMemory = [math]::Round($Memory, 2)
	$MemoryUtilization
```