Convert command from c# to powershell - powershell

Can you please help me converting the below C# to PowerShell
byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + saltBytes.Length];
Below is the full code what I am trying to do here.
I am trying to generate a hash code here
Function CalculateHashWithSalt($input = "Password#123", $salt="qLTf99m__JGu", $algorithmName = "SHA512")
{
$pass = [System.Text.Encoding]::UTF8
$input = "Password123"
$data1 = $pass.GetBytes($input)
$saltbytes = [System.Text.Encoding]::UTF8
$saltbytes=$saltbytes.GetBytes($salt)
$plainTextWithSaltBytes=#()
$plainTextWithSaltBytes = $data1.Length + $saltbytes.Length
for ($i = 0; $i -lt $data1.Length; $i++)
{
$plainTextWithSaltBytes[$i] = $data1[$i]
}
for ($i = 0; $i -lt $saltbytes.Length; $i++)
{
$plainTextWithSaltBytes[$pass.Length + $i] = $saltbytes[$i];
}
[System.Byte[]]::new($hashBytes)
$hashBytes = $algorithmName.ComputeHash($plainTextWithSaltBytes);
$Encrypted = [System.Convert]::FromBase64String($hashBytes)
}
Trying to convert the below c# code :
C# code link

From https://blogs.msdn.microsoft.com/luc/2011/01/21/powershell-getting-the-hash-value-for-a-string/
I have this function in my personal scripts with a parameter for which algo to use.
function Hash($textToHash)
{
$hasher = new-object System.Security.Cryptography.SHA256Managed
$toHash = [System.Text.Encoding]::UTF8.GetBytes($textToHash)
$hashByteArray = $hasher.ComputeHash($toHash)
foreach($byte in $hashByteArray)
{
$res += $byte.ToString()
}
return $res;
}

Related

Split XML by node

I've got a big XML file (more than 4Gb) and i should integrate it into SQL table.
SQL has a 2 Gb limitation. The idea is to split the file into serveral XML. For example 500Mb by file.
I try to adapt a powershell script but i still have the following error
Here is the PowerShell script i'm using and i can't find what's wrong
param( [string]$file = $(throw "ENTITY.XML"), $matchesPerSplit = 50, $maxFiles = [Int32]::MaxValue, $splitOnNode = $(throw "entity"), $offset = 0 )
$ErrorActionPreference = "Stop";
trap {
$ErrorActionPreference = "Continue"
write-error "Script failed: $_ \r\n $($_.ScriptStackTrace)"
exit (1);
}
$file = (resolve-path $file).path
$fileNameExt = [IO.Path]::GetExtension($file)
$fileNameWithoutExt = [IO.Path]::GetFileNameWithoutExtension($file)
$fileNameDirectory = [IO.Path]::GetDirectoryName($file)
$reader = [System.Xml.XmlReader]::Create($file)
$matchesCount = $idx = 0
try {
"Splitting $from on node name='$splitOnNode', with a max of $matchesPerSplit matches per file. Max of $maxFiles files will be generated."
$result = $reader.ReadToFollowing($splitOnNode)
$hasNextSibling = $true
while (-not($reader.EOF) -and $result -and $hasNextSibling -and ($idx -lt $maxFiles + $offset)) {
if ($matchesCount -lt $matchesPerSplit) {
if($offset -gt $idx) {
$idx++
continue
}
$to = [IO.Path]::Combine($fileNameDirectory, "$fileNameWithoutExt.$($idx -$offset)$fileNameExt")
"Writing to $to"
$toXml = New-Object System.Xml.XmlTextWriter($to, $null)
$toXml.Formatting = 'Indented'
$toXml.Indentation = 2
try {
$toXml.WriteStartElement("split")
$toXml.WriteAttributeString("cnt", $null, "$idx")
do {
$toXml.WriteRaw($reader.ReadOuterXml())
$matchesCount++;
$hasNextSibling = $reader.ReadToNextSibling($splitOnNode)
} while($hasNextSibling -and ($matchesCount -lt $matchesPerSplit))
$toXml.WriteEndElement();
}
finally {
$toXml.Flush()
$toXml.Close()
}
$idx++
$matchesCount = 0;
}
}
}
finally {
$reader.Close()
}
My XML file is on the same folder as the PS file and "entity" is the node.

Index was outside the bounds of the array powershell

I want multiple data fetching from excel sheet. I am getting error is Index was outside the bounds of the array.
$Data = Read-Host "Enter the count of Datastore"
$ds = "-sm-"
$Range1 = $Worksheetx1.Range("B1","B1048570")
$Search1 = $Range1.find($ds)
$r = $Search1.row
for ($i=1; $i -le $Data; $i++)
{
$Datastore = #()
$Datastore[$i] = $Worksheetx1.Cells.Item($r, 2).Value2
$r = $r+1
}
$Total_Datastore = $Datastore1 + $Datastore2 + $Datastore3 + $Datastore4
$Total_Datastore
The problem resides in this code:
for ($i=1; $i -le $Data; $i++)
{
$Datastore = #()
$Datastore[$i] = $Worksheetx1.Cells.Item($r, 2).Value2
$r = $r+1
}
You're creating an empty array $Datastore = #(), and try to store data in the second index ($i=1, array index starts at zero, therefore index two). This causes an IndexOutOfRangeException.
Also $Total_Datastore = $Datastore1 + $Datastore2 + $Datastore3 + $Datastore4 doesn't make sense, since $Datastore1 (2,3 and 4) aren't defined anywhere.
Try:
# Only integers are allowed
$Data = [int] (Read-Host "Enter the count of Datastore")
$ds = "-sm-"
$Range1 = $Worksheetx1.Range("B1","B1048570")
$Search1 = $Range1.find($ds)
$r = $Search1.row
$Datastore = #()
for ($i=1; $i -le $Data; $i++) {
# Todo: Check if $r is in a valid range or not !!!
$Datastore += $Worksheetx1.Cells.Item($r, 2).Value2
$r = $r+1
}
$Datastore

PowerShell functions and performance

I've been wondering about the performance impact of functions in PowerShell.
Let's say we want to generate 100.000 random numbers using System.Random.
$ranGen = New-Object System.Random
Executing
for ($i = 0; $i -lt 100000; $i++) {
$void = $ranGen.Next()
}
finishes within 0.19 seconds.
I put the call inside a function
Get-RandomNumber {
param( $ranGen )
$ranGen.Next()
}
Executing
for ($i = 0; $i -lt 100000; $i++) {
$void = Get-RandomNumber $ranGen
}
takes about 4 seconds.
Why is there such a huge performance impact?
Is there a way I can use functions and still get the performance I have with the direct call?
Are there better (more performant) ways of code encapsulation in PowerShell?
a function call is expensive. The way to get around that is to put as much as you can IN the function. take a look at the following ...
$ranGen = New-Object System.Random
$RepeatCount = 1e4
'Basic for loop = {0}' -f (Measure-Command -Expression {
for ($i = 0; $i -lt $RepeatCount; $i++) {
$Null = $ranGen.Next()
}
}).TotalMilliseconds
'Core in function = {0}' -f (Measure-Command -Expression {
function Get-RandNum_Core {
param ($ranGen)
$ranGen.Next()
}
for ($i = 0; $i -lt $RepeatCount; $i++) {
$Null = Get-RandNum_Core $ranGen
}
}).TotalMilliseconds
'All in function = {0}' -f (Measure-Command -Expression {
function Get-RandNum_All {
param ($ranGen)
for ($i = 0; $i -lt $RepeatCount; $i++) {
$Null = $ranGen.Next()
}
}
Get-RandNum_All $ranGen
}).TotalMilliseconds
output ...
Basic for loop = 49.4918
Core in function = 701.5473
All in function = 19.5579
from what i vaguely recall [and can't find again], after a certain number of repeats, the function scriptblock gets JIT-ed ... that seems to be where the speed comes from.

PowerShell StreamReader Change Delimiter

I have a PowerShell script to pull data from a database, but some of the fields contain commas and that is resulting in breaking up the fields because the StreamReader splits it up into fields by comma. How can I change the delimiter of how the data is split into it's fields?
$ConnectionString = "Data Source=server1; Database=Development; Trusted_Connection=True;";
$streamWriter = New-Object System.IO.StreamWriter ".\output.csv"
$sqlConn = New-Object System.Data.SqlClient.SqlConnection $ConnectionString
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand
$sqlCmd.Connection = $sqlConn
$sqlCmd.CommandText = "SELECT * FROM Development.dbo.All_Opportunities WITH(NOLOCK)"
$sqlConn.Open();
$reader = $sqlCmd.ExecuteReader();
# Initialze the array the hold the values
$array = #()
for ( $i = 0 ; $i -lt $reader.FieldCount; $i++ )
{ $array += #($i) }
# Write Header
$streamWriter.Write($reader.GetName(0))
for ( $i = 1; $i -lt $reader.FieldCount; $i ++)
{ $streamWriter.Write($("," + $reader.GetName($i))) }
$streamWriter.WriteLine("") # Close the header line
while ($reader.Read())
{
# get the values;
$fieldCount = $reader.GetValues($array);
# add quotes if the values have a comma or double quote
for ($i = 0; $i -lt $array.Length; $i++)
{
if ($array[$i] -match "`"|\S")
{
$array[$i] = '"' + $array[$i].Replace("`"", "`"`"").ToString() + '"';
}
}
$newRow = [string]::Join(",", $array);
$streamWriter.WriteLine($newRow)
}
$reader.Close();
$sqlConn.Close();
$streamWriter.Close();
Have you read this post to see if it helps your effort. It's for a text fiel, but could open you creativity to what is possible.
'stackoverflow.com/questions/14954437/streamreader-with-tab-delimited-text-file'
FYI, there is no delimiter type called 'field'
Otherwise, for those columns that have a comma as part of the value, a common approach is either to double quote the value or escape it.

CheckedListBox result

I have a CheckedListBox in Powershell. When i select some checkbox the text result is empty.
When i select a second checkbox the first checkbox result text is displayed.
I use the following code for the CheckedListBox:
# Code
$ListView = New-Object System.Windows.Forms.CheckedListBox
$ListView.Location = New-Object System.Drawing.Size(10,40)
$ListView.Size = New-Object System.Drawing.Size(533,325)
$ListView.CheckOnClick = $True
$ListView.Add_ItemCheck({
for ($i = 0; $i - ($ListView.Items.Count-1); $i++)
{
if ($ListView.GetItemChecked($i))
{
$s = $s + $ListView.Items[$i].ToString();
}
}
Write-host $s
})
GetItemChecked($i) will only return the correct result for the item check that raised the event after the event handler has run.
You can inspect the event arguments for the new value of the item:
$ListView.Add_ItemCheck({
param($sender,$e)
$s = ""
for ($i = 0; $i -le ($ListView.Items.Count-1); $i++)
{
# Check if $i is the index of the item we just (un)checked
if($e.Index -eq $i)
{
# Inspect the new checked-state value
if($e.NewValue -eq 'Checked')
{
$s += $ListView.Items[$i]
}
}
elseif ($ListView.GetItemChecked($i))
{
# Item is already checked
$s += $ListView.Items[$i]
}
}
Write-host $s
})