Thursday, April 27, 2023

Linux Basic Commands

## 1. User Environment
Details commands Remarks
loggedInUser whoami
Current User id
Current directory Pwd
List of files \directories ls
ls -lr
ls -ltr

Details commands Remarks
System login processes who -l
who -l -H
Count all login names and number of users logged on who -q -H
who -H
Display the current run level who -r
Display system boot level who -b who -b -r
Display all information who -a -a : Same as -b -d –login -p -r -t -T -u
-b Time of last system boot
-d Print dead processes
-H Print line of column headings
-l Print system login processes
-m Only hostname and user associated with stdin
-p Print active processes spawned by init
-q All login names and number of users logged on
-r Print current runlevel
-t Print last system clock change
-T Add user’s message status as +, – or ?
-u List users logged in

## 2. File Management:


Details Commands Remarks
Create directory mkdir testdir
Copy files cp ./dir/ ./dir2/ cp file.doc newfile.doc
cp main.cs demo.html lib.vb backup
cp main.c demo.h lib.c /home/project/backup/
#Preserve file attributes cp -p filename /path/to/new/location/myfile
#Copy all files in backup folder cp * /home//backup
#Copy all doc files in backup folder
cp *.doc /home/backup
#Copy all files recursively in backup folder
cp -R * /home/backup

#Copy file command with interactive option cp -i foo bar
# Verbose output with cp command cp -v file1 file2

-r - recursive
-v - verbose
Copy files & directories recursively cp ./dir/ ./dir2/ -r -r - recursive
-v - verbose
Move files mv ./file1 ./dir1/ -r - recursive
-v - verbose
Rename files mv ./file1 ./file2 -r - recursive
-v - verbose
Move files from one directory to other directory mv ./dir1 ./dir2 -r - recursive
-v - verbose
Delete files rm ./filename
rm ./filename1 ./filename2 ./filename3
rm *.pdf
-r - recursive
-v - verbose
Delete directories rmdir ./dirName/ -r - recursive
-v - verbose
-i confirmation
To view content of file cat filename cat file
cat /path/file
To create a file called “test.txt”cat > test.txt
##Type following test files and press Ctrl+D at the end of the file This is a line1 in test file.
This is a line2 in file. ## press control-D
cat test.txt
To view big files using shell filters (more, less) cat dwh-log.log | more
cat dwh-log.log | less
more dwh-log.log

less dwh-log.log
To combine two or more files cat test1.txt test2.txt > test-log.txt
cat test-log.txt
To view file with line numbers cat -n test1.txt
cat -number test1.txt
To display TAB characters as ^Icat -T test.txt
To display $ at end of each line,cat -E test.txt
cat --show-ends test.txt
Use ^ and M- notation, except for LFD and TAB and show all nonprintingcat -v test.txt
cat --show-nonprinting testfile.txt
To show allcat -A test.txt
cat --vET test.txt
View all files in directory cat *
cat *.cs
joining binary files cat file1.bin file2.bin file3.bin > large.tar.gz
### extract it
tar -zxvf large.tar.gz
To show allcat -A test.txt
cat --vET test.txt
###  2.1 finding lines using cat , sed and awk commands:
Details Commands Remarks
Read last 100 lines of the filecat {filename} | tail -100
tail -100f {filename}
Example:
cat hugfile.txt| tail -100
tail -100f hugfile.txt
Read first 100 lines of the filecat {filename} | head -100
head -100f {filename}
Example:
cat hugfile.txt | head -100
head -100f hugfile.txt
Print \Read nth line of the file
using SED (stream editor)
cat {filename} | awk 'NR=={n}' Example:
cat hugefile.txt | awk 'NR==25'
Print \Read nth line of the file
using awk
cat {filename} | sed -n '{n}p'
sed -n '{n}p' < {filename}
Example:
cat hugfile.txt | sed -n '100p'
sed -n '100p' < hugfile.txt
Print \Read from mth line to nth lines of the file
using SED (stream editor)
cat {filename} | sed -n '{n},{m}p'
sed -n '{n},{m}p' < {filename}
Example:
cat hugfile.txt | sed -n '10,50p'
sed -n '10,55p' < hugfile.txt
Print \Read from mth line and nth lines of the file
using SED (stream editor)
cat {filename} | sed -n '{m}p;{n}p'
sed -n '{m}p;{n}p' < {filename}
Example:
cat hugfile.txt | sed -n '10p;40p'
sed -n '10p;40p' < hugfile.txt

###  2.2 Replace words file using sed (stream editor) command:
DetailsCommands Remarks
Replacing or substituting string:
Sed command is mostly used to replace the text in a file.
sed 's/{word}/{replacewith}/' {filename}Example:
The below simple sed command replaces the word “data” with “DWH” in the file.
sed 's/data/DWH/' hugefile.txt
Replacing or substituting string:
Sed command is mostly used to replace the text in a file.
sed 's/{word}/{replacewith}/' {filename}Example:
The below simple sed command replaces the word “data” with “DWH” in the file.
sed 's/data/DWH/' hugefile.txt
Replacing the nth occurrence of a pattern in a line:
Use the /1, /2 etc flags to replace the first, second occurrence of a pattern in a line.:
sed 's/{word}/{replacewith}/{n}' {filename}Example:
The below simple sed command replaces the word “data” with “DWH”
in the file for 2nd occurance.
sed 's/data/DWH/2' hugefile.txt
Replacing all the occurrence of the pattern in a line :
The substitute flag /g (global replacement) specifies
the sed command to replace all the occurrences of the string in the line.
sed 's/{word}/{replacewith}/g' {filename}Example:
The below simple sed command replaces the word “data” with “DWH”
in the file fora all occurance.

sed 's/data/DWH/g' hugefile.txt
Replacing from nth occurrence to all occurrences in a line :
The substitute flag /{n}g (global replacement) specifies
the sed command to replace all the occurrences of the string in the line.
sed 's/{word}/{replacewith}/{n}g' {filename}Example:
The below simple sed command replaces the word “data” with “DWH”
in the file for all occurance from nth occurance.

sed 's/data/DWH/5g' hugefile.txt
Replacing from nth occurrence to all occurrences in a line :
The substitute flag /{n}g (global replacement) specifies
the sed command to replace all the occurrences of the string in the line.
sed 's/{word}/{replacewith}/{n}g' {filename}Example:
The below simple sed command replaces the word “data” with “DWH”
in the file for all occurance from nth occurance.

sed 's/data/DWH/5g' hugefile.txt
Parenthesize first character of each word :
This sed example prints the first character of every word in parenthesis.
echo "{Tex}" | sed 's/\(\b[A-Z]\)/\(\1\)/g'Example:
echo "Welcome To The Geek Stuff" | sed 's/\(\b[A-Z]\)/\(\1\)/g'
Replacing string on a specific line number:
restrict the sed command to replace the string on a specific line number.
sed '{n} s/{data}/{ReplaceWith}/' {File}Example:
sed '3 s/data/SWH/' hugefile.txt
Duplicating the replaced line with /p flag:
The /p print flag prints the replaced line twice on the terminal.
If a line does not have the search pattern and is not replaced,
then the /p prints that line only once.
sed 's/{data}/{ReplaceWith}/p' {File.txt}Example:
sed 's/data/SWH/p' hugefile.txt
Replacing string on a range of lines: can specify a range of line numbers to the sed command for replacing a string.
sed '1,3 s/{data}/{ReplaceWith}' {file}Example:
sed '1,3 s/data/DWH' hugefile.txt

###  2.3 Deleting lines from a particular file  using sed (stream editor) command:


#### 2.3.1 To Delete a particular line say n in this example ```sh # Syntax: sed 'nd' {filename} # Example: sed '5d' hugefile.txt ``` #### 2.3.2 To Delete a last line ```sh # Syntax: sed '$d' {filename} #Example: sed '$d' hugefile.txt ``` #### 2.3.3 To Delete line from range x to y ```sh #Syntax: sed 'x,yd' {filename} #Example: sed '3,6d' hugefile.txt ``` #### 2.3.4 To Delete from nth to last line ```sh #Syntax: sed 'nth,$d' {filename} #Example: sed '12,$d' hugefile.txt ``` #### 2.3.5. To Delete pattern matching line ```sh #Syntax: sed '/pattern/d' {filename} #Example: sed '/data/d' hugefile.txt ```

###  2.3 File Management-vi Editor with Commands:


* The vi editor is elaborated as visual editor. It is installed in every Unix system.

The vi editor has two modes:

**Command Mode**:
					In command mode, actions are taken on the file. The vi editor starts in command mode.To enter text, you have to be in insert mode, just type `i`
**Insert Mode**: In insert mode, entered text will be inserted into the file. The Esc key will take you to the command mode from insert mode.
By default, the vi editor starts in Command mode. **To save and quit**:
save and quit vi editor from command mode.
Before writing save or quit command you have to press colon (:). Colon allows you to give instructions to vi. exit vi Commands: ------------------ |Commands| Action|Remarks| | :--- | :---: | ---: | |:wq |Save and quit| | |:w |Save| | |:q |Quit| | |:w fname |Save as fname | | |ZZ || Save and quit| | |:q! | Quit discarding changes made | | |:w! |Save (and write to non-writable file) ||

### 2.4 File Management-list files \directories:
Details commands
List all directories in Unixls -l | grep '^d'
list directories for the current directoryls -d */
find . -maxdepth 1 -type d
List of directories for given directory ls -d /etc/*/ | more
List only files in current directory: ls -l | grep -v '^d'
List all directories in a directory recursively find . -type d -ls |more
find /etc/ -type d -ls
List all files in a directory recursivelyfind . -type f -ls
find /etc/ -type f -ls | more
Put above two aliases in your bash shell startup file:> $ cd
$ vi .bash_profile

Append two lines: You can create two aliases as follows to list only directories and files.
alias lf="ls -l | egrep -v '^d'"
alias ldir='ls -d */' #alias ldir="ls -l | egrep '^d'"
text in files find . -exec grep -rl "<searchText>" {} \;
examples:
find . -exec grep -rl "user" {} \;


###2.5 File Management-How to copy \move files between two unix \linux servers using scp

```sh 
scp [options] username1@source_host:directory1/filename1 \
			  username2@destination_host:directory2/filename2

```
**Details**
* The location of the source file is specified by username1@source_host:directory1/filename1, which includes the:
* Name of the account on the host computer (username1)
* Hostname of the computer on which the source file resides (source_host)
* Name of the directory containing the source file (directory1)
* Filename of the source file (filename1)
* The location to which the source file will be copied is specified by username2@destination_host:directory2/filename2, which includes the:
* Name of the account on the destination computer (username2)
* Hostname of the computer to which the source file will be copied (destination_host)
* Name of the directory to which the source file will be copied (directory2)
* Filename of the copy (filename2)


**Examples**: 

```sh 
  scp ~/sample.txt raz@dev1.aztd.com:~/testdir
  
# It will copy sample.txt from current connected server to testdir folder in dev1 server/
```

```sh 
  scp  -r  raz@dev1.aztd.com:~/dev1-test  ~/testdir
  
# it will copy all files in  dev1-test  directory from dev1 server to testdir directory in connected server recursively.
```

```sh 
  scp  -  raz@dev1.aztd.com:"~/dev1-test/*.txt  ~/testdir
  
# it will copy all text files in  dev1-test directory from dev1 server to testdir directory in connected server.
```

```sh 
  scp   raz@dev1.aztd.com:~/dev1-test/*.pdf  raz@dev2.aztd.com:~/dev2-test ~/testdir
  
# it will copy all pdf files in dev1-test directory from dev1 server to testdir directory in dev2 server.
```

###2.6  File Management- Archiving -Z commands
Details commands Remarks
Uncompressing or UnPacking files gzip -d test.ods.gz Display content after uncompress file
cat test.ods |less
Display the contents of a compressed filezless data.ods.gz
zmore data.ods.gz
Concatenate compressed files with out using gzip & cat zcat TestReadme.gz
Compare compressed files. zdiff file1.gz file2.gz
zcmp test1.gz test2.gz
Search word in Compressed files zegrep -w '^Test1|Test2' Test.gz
zgrep 'wordToSearch' Test.gz
zgrep 'Test' /path/to/log/file.gz
zgrep 'mail' /var/log/maillog-*.gz
zgrep 'error' /var/log/error.log*.gz
zgrep --color 'Failed login for' /var/log/secure*
Search files in a ZIP archive for lines matching a pattern: zipgrep *.cs Project.zip
Search files in a ZIP archive for lines matching a pattern: zipgrep *.cs Project.zip

## 3.Networking

### 3.1 Networking-How to check connectivity of another server server ```sh ping <ipAddress> ping <hostName> ping <FQDNForHostname> Example: ping 172.24.541.100 ping aztd1.azure.com ```

###3.2 Networking-How to check connectivity of another server server over particular port using ssh

```sh 
 ssh -p <portNumer> -v <ipAddress>
 
 ssh -p <portNumer> -v <hostName>
 
 ssh -p <portNumer> -v  <FQDNForHostname>

Example:

	ssh -p 9050 172.24.541.100

	ssh -p 9040  aztd1.azure.com
 
```

Thursday, April 13, 2023

The ways to connect SharePoint using PnP-Powershell module

There are several ways to connect to sharepoint using Connect-PnPOnline

```sh 

# Example :1 

$PnPModule= Get-InstalledModule PnP.Powershell -ErrorAction SilentlyContinue

if($PnPModule -eq $null) { Install-Module -Name "PnP.PowerShell" -RequiredVersion 1.12.0 -Force -AllowClobber }

$URL="https://contso.sharepoint.com/sites/Pre-Screening"

Connect-PnPOnline -Url $URL

```
In this way ,We can connect to SharePoint prompting for the username and password. When a generic credential is added to the Windows Credential Manager with $URL (https://{tenant}.sharepoint.com)
 PowerShell will not prompt for username and password and use those stored credentials instead. 
 
```sh 
# following is the code snippet for adding generic credentials in Windows credentials manager.
 		 
         $credential=Get-credential -Message "Please enter User Name & Password to connect to sharepoint"
         
         $userName=$credential.UserName
         $password=$credential.GetNetworkCredential().Password
         
         cmdkey /generic:$URL /user:$UserName /pass:$password
```
 Note:
 
  - [Needs permission to access resources in your organization that only an admin can grant.](https://learn.microsoft.com/en-us/answers/questions/985641/needs-permission-to-access-resources-in-your-organ)
  - [configure-admin-consent-workflow in Azure AD](https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/configure-admin-consent-workflow)
  - [manage-user-consent-to-applications-in-microsoft-365](https://blog.admindroid.com/manage-user-consent-to-applications-in-microsoft-365/)

------

```sh 
# Example :2 
 
 $URL="https://contso.sharepoint.com/sites/Pre-Screening"
 
 Connect-PnPOnline -url $URL -Interactive
 
```

 In this way , Connects to the Azure AD, acquires an access token and allows PnP PowerShell to access both SharePoint and the Microsoft Graph.
 By default it will use the PnP Management Shell multi-tenant application behind the scenes, so make sure to run `Register-PnPManagementShellAccess` first.

------
```sh 
 # Example :3
 
 $URL="https://contso.sharepoint.com/sites/Pre-Screening"
 Connect-PnPOnline -Url $URL -Credentials (Get-Credential)
    
```
 
 In this way,Connect to SharePoint prompting for the username and password to use to authenticate.

```sh 
# Example :3.1 

		 $credential=Get-credential -Message "Please enter User Name & Password"
         $userName=$credential.UserName
         $password=$credential.GetNetworkCredential().Password
        cmdkey /generic:SharepointCredentials /user:$UserName /pass:$password  #This is one time activity to add generic credentials in Windows credentials manager.
 
        
        $URL="https://contso.sharepoint.com/sites/Pre-Screening"
        
        Connect-PnPOnline -Url $URL -Credentials SharepointCredentials
```
 In this way, Connect to SharePoint for username and password when a generic credential is added to windows credential manager with **"SharepointCredentials"**
    
 
------

```sh 
 # Example :4 
   
   #In this way , Connect to sharepoint using Ceritifcate authentication 
   
   #Get certificate from Certificate Authority and install certificate in mmc.
   
 
 $Config=@{ URL ="https://contso.sharepoint.com/sites/Pre-Screening";
            ClientID=;
            Tenant=;
            ThumbPrint=}
 
  $connection=Connect-PnPOnline -Url $Config.URL -ClientId $Config.ClientID  -Tenant $Config.Tenant  -ThumbPrint $Config.ThumbPrint -ReturnConnection
  
  Get-PnPSite  -Connection $Connection
  Get-PnPList  -Connection $Connection
  
  $Files ="C:\Users\Documents\*.txt"
  $Destination ="Shared Documents/General/Reports"
  
  gci $File | &{Process{ Add-PnPFile -Folder $Destination -Path $.FullName -Value @{Modified=$_.LastWriteTime}  -Connection $connection}}
  
```


In this way, Connect to SharePoint using clientID and clientSecret from App Registration in Azure AD.

------

```sh 
 # Example :5 
   
 $URL="https://contso.sharepoint.com/sites/Pre-Screening"
 
 Connect-PnPOnline -Url $URL -ClientId 344b8aab-389c-4e4a-8fa1-4c1ae2c0a60d -ClientSecret $clientSecret
```

In this way, Connect to SharePoint using clientID and clientSecret from App Registration in Azure AD.

------

```sh 
 # Example :6 
 
  $URL="https://contso.sharepoint.com/sites/Pre-Screening"
 
  Connect-PnPOnline -Url $URL -DeviceLogin
```
 
In this way, Authenticate user using the PnP Management Shell Multi-Tenant application.

A browser window will have to be opened where you have to enter a code that is shown in your PowerShell window.

------

```sh 

 # Example :7
 
 $URL="https://contso.sharepoint.com/sites/Pre-Screening"
 
 Connect-PnPOnline -Url $URL -DeviceLogin -LaunchBrowser

```
This will authenticate you using the PnP Management Shell Multi-Tenant application. 
A browser window will have to be opened where you have to enter a code that is shown in your PowerShell window.

------

```sh  
#Example :8
 
 $URL="https://contso.sharepoint.com/sites/Pre-Screening"
 
 Connect-PnPOnline -Url $URL -UseWebLogin:$true
 
 Get-PnPTeamsTeam 
 Get-PnPList 

```
 - Connects to SharePoint using legacy cookie based authentication. 
 - Notice this type of authentication is limited in its functionality. We will for instance not be able to acquire an access token for the Graph, 
   and as a result none of the Graph related cmdlets will work. Also some of the functionality of the provisioning engine
 
 - Get-PnPSiteTemplate, Get-PnPTenantTemplate, Invoke-PnPSiteTemplate, Invoke-PnPTenantTemplate) will not work because of this reason. 
 
 - The cookies will in general expire within a few days and if you use -UseWebLogin within that time popup window will appear that will disappear immediatel #>

------

```sh 
	# Example :9
    
    $URL="https://contso.sharepoint.com/sites/Pre-Screening"
    
    Connect-PnPOnline -Url $URL -ManagedIdentity
    
``` 
   
  - Connects using a system assigned managed identity to Microsoft Graph.
  - Using this way of connecting only works with environments that support managed identities: Azure Functions, Azure Automation Runbooks and the Azure Cloud Shell.
    
------

```sh
	#Example :10
     
    $URL="https://contso.sharepoint.com/sites/Pre-Screening"
    
    Connect-PnPOnline -Url $URL -ManagedIdentity -UserAssignedManagedIdentityObjectId 623c1b21-6611-47fd-a616-674d3aec2a52

``` 

  - Connects using an user assigned managed identity with object/principal ID 623c1b21-6611-47fd-a616-674d3aec2a52 to SharePoint Online.
  - Using this way of connecting only works with environments that support managed identities: Azure Functions, Azure Automation Runbooks and the Azure Cloud Shell.
    
------

How to access sharepoint items using powershell


We can access sharepoint items\sites using following powershell modules.
 
 1. SPO (SharepointPnpPowershellOnline) Module 
 
 2. PnP.Powershell module 
 
SPO (sharepointPnpPowershellOnlin) Module Vs PnP.Powershell module

1. PnP PowerShell Cmdlets works in the context of the current user, where as SPO (sharepointPnpPowershellOnline command) runs with the Tenant Admin rights. 

2. PnP PowerShell Cmdlets connects to the SiteCollection level, where as SPO has the commands to target Tenant level.

3. SPO module works only in SharePoint Online where as pnp. powershell is a cross platform library.

4. SPO is legecy version of PnP Powershell

5. What are the advantages of PnP in SharePoint?

6. The main advantage of using SharePoint PnP is, It reduced the code to get the required information by using only a single line of code so you can retrieve the object, once the client context is set. 
  
7. By using PnP in SharePoint Online development, developers will be more efficient and productive.

Upgrade SPO module to PnP Powershell module

```sh
$SPOModule=Get-InstalledModule  sharepointPnpPowershellOnline  -ErrorAction SilentlyContinue 

if($SPOModule  -ne $null){ Uninstall-Module  sharepointPnpPowershellOnline -Force -ErrorAction SilentlyContinue}

$PnPModule= Get-InstalledModule PnP.Powershell -ErrorAction SilentlyContinue

if($PnPModule -eq $null) { Install-Module -Name "PnP.PowerShell" -RequiredVersion 1.12.0 -Force -AllowClobber }
```

Note: Dont install latest PnP.Powershell with version 2.1.1. there is problem with this version
Problem:
  		Import-Module : Could not load file or assembly 'System.Management.Automation] Issue Symptom: unable to run PnP PowerShell commands using PowerShell ISE in administrative mode. Getting following error
    
    	Exception: Import-Module : Could not load file or assembly 'System.Management.Automation, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified.
Solution:

1. Uninstall all versions and then install correct 1.12.0 version because Newer version (2.1.1) of PnP PowerShell  has issues #1. This issue happened with newer version PnP PowerShell 2.1.1.
  
```sh 
  Uninstall-Module PnP.PowerShell 
```

2. Install PnP.PowerShell with version 1.12.0

```sh 
   Install-Module -Name "PnP.PowerShell" -RequiredVersion 1.12.0 -Force -AllowClobber
```


Following is the powershell script to upload files to sharepoint from local drive


```sh

Install-Module -Name "PnP.PowerShell" -RequiredVersion 1.12.0 -Force -AllowClobber 

#Ex:- $URL="https://{tenant-name}.sharepoint.com/sites/{site-name}"

$URL="https://contso.sharepoint.com/sites/Pre-Screening"

$SourcePath="D:\Pre-Screening-DocLib"
$DestinationPath="Shared Documents/General/Pre-Screening"

#Connect to sharepoint

Connect-PnPOnline -Url $URL -Interactive -UseWeblogin:$true

## upload local files Sharepoint  

gci $SourcePath |ForEach-Object  -Process {Add-PnPFile -Path $_.FullName -Folder $DestinationPath -Values @{Modified=$_.LastWriteTime}}

```

Wednesday, April 12, 2023

How to skip SkipCertificateCheck

I am getting below error while calling Invoke-WebRequest and Invoke-RestMethod commandlets in powershell. Problem:-1
Invoke-WebRequest : The underlying connection was closed: Could not establish trust relationship for SSL/TLS secure channel At line:2 char:6 + $r= Invoke-WebRequest -Uri $url -Headers $headers + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Solution:

1.Add Type 'ServerCertificateValidationCallback to define metod SkipCertificateCheck to skip certificate check.

```sh
if (-not ([System.Management.Automation.PSTypeName]'ServerCertificateValidationCallback').Type)
    {
		$certCallback = "
			using System;
			using System.Net;
			using System.Net.Security;
			using System.Security.Cryptography.X509Certificates;
			public class ServerCertificateValidationCallback
			{
				public static void SkipCertificateCheck()
				{
					if(ServicePointManager.ServerCertificateValidationCallback ==null)
					{
						ServicePointManager.ServerCertificateValidationCallback += 
							delegate
							(
								Object obj, 
								X509Certificate certificate, 
								X509Chain chain, 
								SslPolicyErrors errors
							)
							{
								return true;
							};
					}
				}
			}
		"
			Add-Type -TypeDefinition $certCallback -Language CSharp 
	}

```
2.Call SkipCertificateCheck() method before calling Invoke-WebRequest and Invoke-RestMethod commandlets in powershell.

```sh 
	[ServerCertificateValidationCallback]::SkipCertificateCheck()
    Invoke-WebRequest -Uri "https://www.nuget.org/" 
```

Problem:2
Note: Don't set SecurityProtocol to Tls12 if using windows 10 and lower version of Windows 2016

```sh 
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
```
If set SecurityProtocol as Tls12 then response of Invoke-WebRequest and Invoke-RestMethod commandlets will return below exception
Invoke-WebRequest : The underlying connection was closed: An unexpected error occurred on a send. At line:2 char:6 + $r= Invoke-WebRequest -Uri $url -Headers $headers + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 
Due to PowerShell defaults, it’s not unusual to have issues with TLS. 
 
The ambiguous nature of this error did however make me jump to the conclusion that I probably just needed to enforce TLS 1.2. This can be done using this PowerShell one-liner 
 but it doesn't solve problem 

```sh

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

```
Solution: The resolution and solution for the problem is to allow TLS, TLS 1.1 and TLS 1.2. Insert the following line before invoking your PowerShell WebRequest using either Invoke-RestMethod or Invoke-WebRequest.

```sh

[Net.ServicePointManager]::SecurityProtocol = = [Net.SecurityProtocolType]::Tls -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls12

```
Solution: Just close powershell IDE\window and reopen n then Powershell defaults will be restored then it will solve the problem

Problem with deployments of automatically sequence by dacpac deployment using SqlPackage


Publish script is always includes restarting the sequence back to the 'start with' or 'minvalue' value.

How can I prevent to update sequence value by dacpac deployment using SqlPackage? .it means how to keep current value of sequence post dacpac deployment.

For example

```sql
CREATE SEQUENCE [dbo].[UUID_Sequence]
    AS NUMERIC (8)
    INCREMENT BY 1
    MINVALUE 10000
    CACHE 20;
```
and the publish script always includes the following:

```sql
ALTER SEQUENCE [dbo].[UUID_Sequence]
    RESTART WITH 10000;
GO
```
If exclude sequence object using publish profile but you have to manually deploy sequences so it will prevent to restart to initial value . it wont create sequence object if deploy in new environment so this solution wont solve problem completely.

```sh
::from Database publish profile file
	True

::from command line
	/p:ExcludeObjectType=Sequences
```
Solution: We can solve this issue by using below pre and post deployment scripts Pre-Deployment:
```sql
-- Capture next value of sequence UUID_Sequence for reseeding in post-deployment phase.
IF EXISTS (SELECT 1 FROM sys.sysobjects WHERE name = 'UUID_Sequence' AND [type] = 'SO')
BEGIN
	DECLARE @NextValue_UUID_Sequence decimal(28,0)
	SELECT @NextValue_UUID_Sequence = NEXT VALUE FOR dbo.UUID_Sequence;

	PRINT 'Sequence UUID_Sequence: current value is ' + CAST(@NextValue_UUID_Sequence AS VARCHAR(28))

	-- Store in a temp table for retrieval during reseed.
	SELECT @NextValue_UUID_Sequence AS NextValue INTO #Seed_UUID_Sequence
END
```
Post-Deployment:
```sql
/*
    This script reseeds dbo.UUID_Sequence to it's next value at the beginning of the deployment.
 */
IF OBJECT_ID('tempdb..#Seed_UUID_Sequence') IS NOT NULL
BEGIN
    DECLARE @fID VARCHAR(28)

	SET @fID = (SELECT NextValue FROM #Seed_UUID_Sequence)

    -- Prepare the statement to reseed the sequence
    DECLARE @sql NVARCHAR(MAX) = N'ALTER SEQUENCE dbo.UUID_Sequence RESTART WITH ' + @fID
    --PRINT @sql

    -- Execute
    EXEC sp_executesql @sql

    PRINT N'Sequence dbo.UUID_Sequence: seeded to '  + @fID
    drop table ##Seed_UUID_Sequence'
END
GO
```

Monday, April 3, 2023

Convert Json string to hashtable


Powershell stores json string psobject type  
1. Define empty Hashtable
2. Iterate each property of psobject 
3. Add value of psobject into Hashtable with name property as key/

Here is the script for convert JSON string to Hashtable.

```sh

      
 function  ConvertJson-ToHashTable(){
    [CmdletBinding()]
            Param(
            [Parameter(Mandatory=$true,ValueFromPipeline=$true )]
            [psobject] $inputObj)
    $hash = @{}
    $inputObj.psobject.properties | foreach{$hash[$_.Name]= [string[]]$_.Value}
    return  $hash
}
```