PowerShell is an amazing tool which we can use to perform various operations in windows environments. Today we are going to write a PowerShell script using Windows PowerShell ISE.
How to open Windows PowerShell ISE
For this session we need to have Windows PowerShell ISE. You can find it under, Control Panel\All Control Panel Items\Administrative Tools.
You better open Windows PowerShell ISE as administrator mode. if you have any issues please follow this link. Windows PowerShell Integrated Scripting Environment (ISE)
In My project I had to use PowerShell script to regiter few Dlls in Global Assembly Cache (GAC) and keep file paths in XML file and extract data by reading XML file. My XML file looks like this and file name is FilePath.XML.
FilePath.XML
<?xml version="1.0" encoding="utf-8"?>
<Resource>
<MacroFilePath>\ReleaseBuild\ReleaseMacro.mac</MacroFilePath>
<ProductName>BCS</ProductName>
<GPVersion>GP2016</GPVersion>
<CompatiblityID>16</CompatiblityID>
<MajorVersion>16</MajorVersion>
<MinorVersion>0</MinorVersion>
<BuildNumber>117</BuildNumber>
<AutoUpdateBuildNumber>0</AutoUpdateBuildNumber>
<FormDictionary>BCSF.DIC</FormDictionary>
<ReportDictionary>BCSR.DIC</ReportDictionary>
<DefaultChunk>BCS.CNK</DefaultChunk>
<DefaultExtract>BCS.DIC</DefaultExtract>
<DefaultGPSDKDirectory>GP2016 VS Tools SDK</DefaultGPSDKDirectory>
<GacUtilLocation>C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools</GacUtilLocation>
<PackagingLocation></PackagingLocation>
<DictionaryPath></DictionaryPath>
<ExtractPath></ExtractPath>
<ChunkPath></ChunkPath>
<DefaultLocation>ReleaseBuild</DefaultLocation>
<AssemblyLocaion></AssemblyLocaion>
<ChunckLocation></ChunckLocation>
<GpLocaion></GpLocaion>
<GPVSToolsSDK></GPVSToolsSDK>
<DynamicsSetLocaion>C:\Program Files (x86)\Microsoft Dynamics\GP2016\DYNAMICS.SET</DynamicsSetLocaion>
</Resource>
GetSource.ps1
Now I need to read this XML file from PowerShell script. In order to do that i have written a script call GetSource.ps1. There I can pass a node as parameter which I need to read the value.#GET SOURCE
#==========================================================================================================================================================================
Function GetSource ([string] $NodeToFind)
{
try{
$invocation = (Get-Variable MyInvocation).Value
$directorypath = $invocation.PSScriptRoot
$parentPath = Split-Path -parent $directorypath
if([string]::IsNullOrEmpty($parentPath))
{
$XMLPath = $directorypath + '\FilePath.xml'
#$XMLPath = $directorypath + '\ResourceFile.xml'
}
else
{
$XMLPath = $parentPath + '\FilePath.xml'
}
[xml]$xml= [xml](Get-Content $XMLPath)
[string] $Source = $xml.GetElementsByTagName($NodeToFind).InnerXML
return $Source;
}
catch{
throw $_
return
}
}
#==========================================================================================================================================================================
CopyFiles.ps1
Now I'm going to write PowerShell function to copy required file to given destinations. This function is a general one which we can pass Source and Destination as Parameters and get the files copied.#COPY DLLS
#==========================================================================================================================================================================
Function Copy-Required-DLLs([string] $Source, [string] $Destination){
while(1){
try{
if( Test-Path $Source.Trim())
{
Copy-Item $Source $Destination
Write-host "$Source Copied to $Destination"
return
}
else
{
Write-Error "File $Source not found"
exit
}
}
catch [System.IO.IOException] {
if($_.Exception.HResult -eq -2147024864){
Start-Sleep -Milliseconds 500
Write-Host '-' -NoNewline
}else{
throw $_
return
}
}
catch{
throw $_
return
}
}
}
#==========================================================================================================================================================================
RegisterAssembly.ps1
Then we need to register all the copied DLLs in Global Assembly cache (GAC). To make that happen we are going to write another PowerShell Script. In this script we are going to pass file info as a parameter and also we are going to refer GetSource.ps1 and use GetSource function to read FilePath.XML file.
$this_path is a variable that holds the execution directory path and
[System.IO.DirectoryInfo](Split-Path((Get-Variable MyInvocation).Value.MyCommand.Path)) returns the execution path.
$this_path = [System.IO.DirectoryInfo](Split-Path ((Get-Variable MyInvocation).Value.MyCommand.Path))
.$this_path\GetSource.ps1
#REGISTER DLLS
#==========================================================================================================================================================================
Function Register-Required-Dlls{
Param(
[Parameter()]
[IO.FileInfo]$Dll
)
while(1){
try{
if($Dll.Exists){
[string] $GacUtilLocation = GetSource -NodeToFind "GacUtilLocation";
Set-Location -Path $GacUtilLocation
.\gacutil.exe /i $Dll
Write-Verbose "$Dll Installed.."
return
}else{
Write-Error "File $Dll not found"
exit
}
}
catch [System.IO.IOException] {
if($_.Exception.HResult -eq -2147024864){
Start-Sleep -Milliseconds 500
Write-Host '-' -NoNewline
}else{
throw $_
return
}
}
catch{
throw $_
return
}
}
}
#==========================================================================================================================================================================
Finally we are going to assemble the peaces we have written into a script which we can achieve the goal. Now we are creating PowerShell script called RegisterForMaualProcess.ps1.
RegisterForMaualProcess.ps1
$this_path = [System.IO.DirectoryInfo](Split-Path ((Get-Variable MyInvocation).Value.MyCommand.Path)).$this_path\RegisterAssembly.ps1
.$this_path\CopyFiles.ps1
[string] $MyAssembly = GetSource -NodeToFind "AssemblyLocaion" ;
[string] $GpLocaion = GetSource -NodeToFind "GpLocaion" ;
[string] $GPVSToolsSDK = GetSource -NodeToFind "GPVSToolsSDK" ;
[string] $ChunckLocation = GetSource -NodeToFind "ChunckLocation" ;
[string] $DefaultLocation = GetSource -NodeToFind "DefaultLocation";
[string] $DefaultChunk = GetSource -NodeToFind "DefaultChunk";
[string] $GPVersion = GetSource -NodeToFind "GPVersion";
#If null or empty set Default
if ([string]::IsNullOrEmpty($MyAssembly))
{
[string] $AssemblyPath = Split-Path ($this_path)
$MyAssembly = "$AssemblyPath" +"\GP.Interop.dll"
}
if ([string]::IsNullOrEmpty($GpLocaion))
{
$GpLocaion = "C:\Program Files (x86)\Microsoft Dynamics\"+"$GPVersion\"
}
if ([string]::IsNullOrEmpty($GPVSToolsSDK))
{
$GPVSToolsSDK = "C:\Program Files (x86)\Microsoft Dynamics\"+"$GPVersion VS Tools SDK\"
}
if([string]::IsNullOrEmpty($ChunckLocation))
{
$ChunckLocation = "$this_path\" + $DefaultChunk;
}
#COPY GP.Interop.dll
#==========================================================================================================================================================================
Write-Host "Start to copy GP.Interop.dll..."
Copy-Required-DLLs -Source $MyAssembly -Destination $GpLocaion -v
Write-Host "GP.Interop.dll copied to $GPVersion" -foregroundcolor "yellow"
Copy-Required-DLLs -Source $MyAssembly -Destination $GPVSToolsSDK -v
Write-Host "GP.Interop.dll copied to $GPVersion VS Tools SDK" -foregroundcolor "yellow"
Copy-Required-DLLs -Source $MyAssembly -Destination C:\Windows\Microsoft.NET\Framework\v2.0.50727 -v
Write-Host "GP.Interop.dll copied to $GPVersion VS Tools C:\Windows\Microsoft.NET\Framework\v2.0.50727" -foregroundcolor "yellow"
Write-Host "Done..." -foregroundcolor "green"
#==========================================================================================================================================================================
Register-Required-Dlls C:\Windows\Microsoft.NET\Framework\v2.0.50727\GP.Interop.dll -v
when you run the program, these files we need to keep that in the execution path since it refers each other.
Comments
Post a Comment