Endianness data storage

I was originally looking at generating random numbers in PowerShell by using the .NET class [System.Security.Cryptography.RandomNumberGenerator]. At some point I got sidetracked and wondered how two and four byte numbers were stored in my byte array. So hence the following code to look at at things.

function Show-Endian {
[CmdletBinding()]
[OutputType([System.Void])]
param()

  # true if the architecture is little-endian;
  # false if it is big-endian.
  $endi = '';
  if ([System.BitConverter]::IsLittleEndian) {
      $endi = 'little endian';
  } else {
      $endi = 'big endian';
  }
  Write-Output ('This computer appears to be {0}' -f $endi);
}

function Part-Two {
[CmdletBinding()]
[OutputType([System.Void])]
param()

  [System.Byte]$my8 = 0;       # Represents an 8-bit unsigned integer.
  [System.UInt16]$my16 = 0;    # Represents a 16-bit unsigned integer.
  [System.UInt32]$my32 = 2041; # Represents a 32-bit unsigned integer.

  $data = New-Object Byte[] 4;
  $data.Clear();

  Write-Output '';
  $mynum = $my32;

  Write-Output 'Unsigned bytes';
  Write-Output ('Maximum value: {0:X2}' -f [System.Byte]::MaxValue);
  Write-Output ('Minimum value: {0:X2}' -f [System.Byte]::MinValue);

  Write-Output '';
  Write-Output ('mynum is now decimal {0:N0}, hex {1:X2}' -f $mynum,$mynum);
  Write-Output ('data has size of {0} bytes' -f $data.Length);

  # convert the number in variable 'mynum' to the array
  # 'data'.
  $data = [System.BitConverter]::GetBytes($mynum);
  Write-Output '';
  Write-Output 'Looking at positions in the array'
  for ($i = 0; $i -lt $data.Length; $i++) {
      Write-Output ('Position {0} = {1:X2}' -f $i,$data[$i]);
  }

 }

$png = [System.Security.Cryptography.RandomNumberGenerator]::Create();
# -----
Show-Endian;
Part-Two;
# -----
$png.Dispose();
Write-Output 'End of test';

 

By running the script, we can see what’s happening.


This computer appears to be little endian

Unsigned bytes
Maximum value: FF
Minimum value: 00

mynum is now decimal 2,041, hex 7F9
data has size of 4 bytes

Looking at positions in the array
Position 0 = F9
Position 1 = 07
Position 2 = 00
Position 3 = 00
End of test

Hex 7F9 is stored in two bytes of our four byte array. F9 is stored in $data[0], and the remaining number, 7, is stored in $data[1]. Of course, for our test we could have used a two byte array to store the number used in our example.

 

The Wikipedia article at https://en.wikipedia.org/wiki/Endianness gives a good understanding of big-endian and little-endian.

 

Keywords: big-endian, little-endian, Endianness, byte, bitconverter

 

 

Advertisements
Posted in powershell | Leave a comment

Centre PowerShell forms

The .NET Framework class Form represents a window or dialog box that makes up an application’s user interface. In other words this is how we can build a GUI interface to an application with forms and dialog boxes.

 

The StartPosition property of the form is a way of being able to specify the initial starting position of a form. So this is useful if we wish to place the form in the centre of the screen. Use the following code to achieve this:

 

#Sets the starting position of the form at run time.
$CenterScreen = [System.Windows.Forms.FormStartPosition]::CenterScreen;
$form1.StartPosition = $CenterScreen;

 

The enumeration type System.Windows.Forms.FormStartPosition has several members to choose from and the one we’re interested in is CenterScreen. From the documentation, the description for this member is:

 

The form is centered on the current display, and has the dimensions specified in the form’s size.

 

If your PowerShell session does not seem to know about forms, then import the assembly.

[reflection.assembly]::loadwithpartialname(“System.Windows.Forms”) | Out-Null

 

The following loop will show the other members of System.Windows.Forms.FormStartPosition.

 

foreach ($m in [System.Enum]::GetValues([System.Windows.Forms.FormStartPosition]))
{ Write-Host ([int]$m): $m }

 

See also

How to Create and Use Enums in Powershell
https://social.technet.microsoft.com/wiki/contents/articles/26436.how-to-create-and-use-enums-in-powershell.aspx

 

Keywords: powershell form center centre start position

 

 

 

 

Posted in powershell | Tagged | Leave a comment

List lines from a text file

There may come a time when you want to display just a few lines from a text file. The following PowerShell code can be used to achieve this.

The examples will be based upon a sample text file containing the lines:


the,1
quick,2
brown,3
fox,4
jumps,5
over,6
the,7
lazy,8
dog,9

1.

In this example, the parameter TotalCount of the Get-Content cmdlet specifies the number of lines from the beginning of a file. The default is -1 (list all lines).

Get-Content -Path myfile.txt -TotalCount 3

Sample output:

the,1
quick,2
brown,3

You can also achieve this with:

Get-Content myfile.txt -First 3

2.

Doing this from the other end, the Get-Content cmdlet parameter Tail lists lines from the end of the file. This parameter specifies the number of lines from the end of a file.

Get-Content -Path myfile.txt -Tail 3

Sample output:

the,7
lazy,8
dog,9

3.

First and last few lines.

If you really wanted to, you could pipe the output from the Get-Content cmdlet into the Select-Object and make use of the First and Last parameters to look at the first few or last lines in the file.

  • First – Gets only the specified number of objects. Enter the number of objects to get.
  • Last – Specifies the number of objects to select from the end of an array of input objects.

Examples

Get-Content -Path myfile.txt | Select-Object -First 3

or

Get-Content -Path myfile.txt | Select-Object -Last 4

Lines in the middle of the file.

To look at lines other than the first or last, we could use the Select-Object parameter Index.

From the documentation:

-Index

Selects objects from an array based on their index values. Enter the indexes in a comma-separated list.

Indexes in an array begin with 0, where 0 represents the first value and (n-1) represents the last value. IE, the array is zero-based.

This means we have to subtract 1 from the line number(s) in question. To look at lines 4,5 and 6 inclusive, we have to specify line numbers 3,4 and 5.

Get-Content -Path myfile.txt | Select-Object -Index 3,4,5

will give you:

fox,4
jumps,5
over,6

Of course, if you’d like to skip some lines, then use the following:

Get-Content -Path myfile.txt | Select-Object -Skip 4

Posted in powershell | Tagged , | Leave a comment

Enumerating over objects

Looping Through a Collection of Objects.

There are two ways of enumerating over objects. One may be considered easier than the other. Nevertheless the two ways are shown below.

1.

Using a WHILE loop and GetEnumerator.

$lines = @('a', 'b', 'c', 'd', 'e', 'f');
$enumerator = $lines.GetEnumerator();

while ($enumerator.MoveNext()) {
    $enumerator.Current;
}

2.

Using a foreach loop.

$lines = @('a', 'b', 'c', 'd', 'e');
foreach ($item in $lines) {
   Write-Host $item;
}

See also

Foreach-Object Cmdlet

Posted in powershell | Tagged , | Leave a comment

Creating CSV files for use with Excel

CSV files

Working on a recent project, I was using PowerShell to manipulate a list of MS Word documents that I had to process. Reading other articles on the Internet, I realised how useful it would be if I could create a list of files of interest in a CSV file and import this into Microsoft Excel in the usual way.

Although the example given is looking at PDF files, the principle is the same.

$inputPath='C:\pdf_files';
$outputCsv='C:\temp\pdfs.csv';

Get-ChildItem -Path $inputPath -Filter *.pdf -Recurse |
    Select-Object DirectoryName, Name, LastWriteTime |
    Export-Csv -Path $outputCsv -Encoding ascii -NoTypeInformation;

The Select-Object Cmdlet is used to select the file attributes I want in my CSV file.

 

See also

Use PowerShell to Create CSV File to Open in Excel

Using the Select-Object Cmdlet

Select-Object Cmdlet
 

Keywords: powershell csv import


							
Posted in powershell | Tagged , | Leave a comment

PowerShell and Unix crontables

Recently, I working on ways of documenting crontables we had on the various Unix servers we had a responsibility for. In the end I opted for a PowerShell solution to create an XML file for each of the crontables.

The program looks as follows:

# Creates an XML file from the output of the Unix command
# $ crontab -l > cron.txt.
#
# This program is also an example of creating XML files from PowerShell.
#

function Write-Dataline($xwriter, $cronbits, $id) {

  $xwriter.WriteStartElement("Line");
  $xwriter.WriteAttributeString("ID", "$id");

  $xwriter.WriteStartElement("CronTime");
  $xwriter.WriteString($cronbits.DateTime);
  $xwriter.WriteEndElement();

  $xwriter.WriteStartElement("Executable");
  $xwriter.WriteString($cronbits.Executable);
  $xwriter.WriteEndElement();

  $xwriter.WriteStartElement("Logfile");
  $xwriter.WriteString($cronbits.Logfile);
  $xwriter.WriteEndElement();

  $xwriter.WriteStartElement("ErrorRedirect");
  $xwriter.WriteRaw($cronbits.ErrorRedirect);
  $xwriter.WriteEndElement();
write-output ("error thing = $($cronbits.ErrorRedirect)");
  $xwriter.WriteFullEndElement();     # <-- Close element ''Line''.

} #end function Write-Dataline

function Close-XmlFile($xwriter) {

  Write-Host "Closing the xml file";
  # The closing bits of the XML file
  $xwriter.WriteEndElement();     # <-- Close root element
  $xwriter.WriteEndDocument();    # <-- Close the document

  # Finish The Document
  $xwriter.Finalize;
  $xwriter.Flush;
  $xwriter.Close();

} #end function Close-XmlFile

function Get-Lineparts([String]$str) {
  begin {
    $props = [ordered]@{
       DateTime = "";
       Executable = "";
       Logfile = "";
       ErrorRedirect = "";
    }
    $cronbits = New-Object psobject -Property $props;

    $props = [ordered]@{
       Start = 0;
       End = 0;
    }
    $pos = New-Object psobject -Property $props;
  } #end begin


  process {

    # Get the date/time part of the cron line.
    $pos.End=$str.IndexOf('/');
    $cronbits.DateTime=$str.Substring($pos.Start,$pos.End).Trim();

    # Get the executable, i.e. the shell script bit.
    $pos.Start=$pos.End;
    $pos.End=$str.IndexOf('>', $pos.End);
    $cronbits.Executable=$str.Substring($pos.Start,($pos.End-$pos.Start)).Trim();

    # Get the logfile name.
    $pos.Start=$str.IndexOf('/', $pos.End);
    $pos.End=$str.IndexOf('2>&1', $pos.End);
    $cronbits.Logfile=$str.Substring($pos.Start,($pos.End-$pos.Start)).Trim();

    # Get the error redirect.
    $cronbits.ErrorRedirect=$str.Substring($pos.End).Trim();

  } #end process


  end {
    return $cronbits;
  } #end end

} #end function Get-Lineparts

function Set-XmlWriterSettings {

  $xsettings = New-Object -TypeName System.Xml.XmlWriterSettings;
  $xsettings.CloseOutput = $true;
  $xsettings.Encoding = [System.Text.Encoding]::UTF8;
  $xsettings.Indent = $true;
  $xsettings.IndentChars = "    "; # 4 spaces
  $xsettings.WriteEndDocumentOnClose = $true;
  $xsettings.CheckCharacters = $true;
  #$xsettings.NewLineChars = "0xoa";
  $xsettings.NewLineOnAttributes = $true;
  $xsettings.OmitXmlDeclaration = $false;
  $xsettings.ConformanceLevel = [System.Xml.ConformanceLevel]::Auto;

  return $xsettings;

} #end function Set-XmlWriterSettings

function Set-XmlFile {

  # Do some initialising
  $filePath = "C:\ian\PowerShell\good03.xml";
  $xset = Set-XmlWriterSettings;
  [System.Xml.XmlWriter]$xwriter = [System.Xml.XmlWriter]::Create($filePath,$xset);
  $server="MyServer";
  $owner="Ian";
  $ymd=(Get-Date).ToString("s");

  # Write the header elements to our XML file
  $xwriter.WriteStartDocument();               # <-- Start the document
  $xwriter.WriteStartElement("CronTable");     # <-- Important root element

  $xwriter.WriteStartElement("Server");
  $xwriter.WriteString($server);
  $xwriter.WriteEndElement();

  $xwriter.WriteStartElement("CronOwner");
  $xwriter.WriteString($owner);
  $xwriter.WriteEndElement();

  $xwriter.WriteStartElement("DateStamp");
  $xwriter.WriteString($ymd);
  $xwriter.WriteEndElement();

  $xwriter.WriteStartElement("CronLines");

  return $xwriter;

} #end function Set-XmlFile


# ------------------------
# Main routine starts here
# ------------------------

$counter=0;
$infile="C:\ian\PowerShell\single_line.txt";
$input = New-Object -TypeName System.IO.StreamReader -ArgumentList $infile;
$ymd=(Get-Date).ToString("s");
$cronbits=$null;

#Create and write the header to the XmlFile.
$xwriter=Set-XmlFile;

$inrec = $input.ReadLine();
while ($inrec -ne $null) {
   Write-Output ($inrec);
   $counter++;
   $cronbits=Get-Lineparts $inrec;
   Write-Dataline $xwriter $cronbits $counter;
   $cronbits | Format-list;

   $inrec = $input.ReadLine();
}

$input.Close();
$input.Dispose();

Close-XmlFile($xwriter);

Write-Host "`nRecords read: $counter";
Write-Host "The date is $ymd";

Input and output files are hard coded so the program could be more flexible.

Input file – is at line 148.

Output file – is at line 113.

The input file is created on the Unix server with the command:

$ crontab -l > inputfile.txt

The man page will cover this command. The input file I used was:

15,30,45,0 * * * * /u01/Acer/MorrisGarages/exec/GreenBank.sh > /u01/Acer/MorrisGarages/GreenBank.log 2>&1
45 19 * * * /u04/Acer/Minolta/exec/Hartung–Boothroyd.sh > /u04/Acer/Minolta/logs/Hartung–Boothroyd.log 2>&1
25 04 * * * /u04/Boeing/Digital/Jodrell-Bank.sh > /u04/Boeing/Digital/Jodrell-Bank.log 2>&1

The output XML file will look like this:

<?xml version="1.0" encoding="utf-8"?>
<CronTable>
    <Server>MyServer</Server>
    <CronOwner>Ian</CronOwner>
    <DateStamp>2015-04-05T18:49:17</DateStamp>
    <CronLines>
        <Line
            ID="1">
            <CronTime>15,30,45,0 * * * *</CronTime>
            <Executable>/u01/Acer/MorrisGarages/exec/GreenBank.sh</Executable>
            <Logfile>/u01/Acer/MorrisGarages/GreenBank.log</Logfile>
            <ErrorRedirect>2>&1</ErrorRedirect>
        </Line>
        <Line
            ID="2">
            <CronTime>45 19 * * *</CronTime>
            <Executable>/u04/Acer/Minolta/exec/Hartung–Boothroyd.sh</Executable>
            <Logfile>/u04/Acer/Minolta/logs/Hartung–Boothroyd.log</Logfile>
            <ErrorRedirect>2>&1</ErrorRedirect>
        </Line>
        <Line
            ID="3">
            <CronTime>25 04 * * *</CronTime>
            <Executable>/u04/Boeing/Digital/Jodrell-Bank.sh</Executable>
            <Logfile>/u04/Boeing/Digital/Jodrell-Bank.log</Logfile>
            <ErrorRedirect>2>&1</ErrorRedirect>
        </Line>
    </CronLines>
</CronTable>

The XML tag CronLines contain details of each of the lines in my example input file. The ID attribute indicating which line in particular. So the tag <Line ID=”3″> gives the detail for line 3 of my input file, Jodrell-Bank.sh.

Lines 156-165 is the main processing loop in which each line is read in from the input file.

Line 160 invokes function Get-Lineparts passing to it, an input record.

Funtion Set-XmlWriterSettings specifies a set of features to support on the XmlWriter object. See XmlWriterSettings Class for further details. This is really initialising my XML object. How many character spaces to indent and so on.

Function Write-Dataline writes data to the tags CronTime, Executable, Logfile and ErrorRedirect.

Function Get-Lineparts tokenizes the input string record into its constituent parts.

Posted in powershell | Tagged , | Leave a comment

.NET List Class

The .NET List Class represents a strongly typed list of objects. It also provides methods to search, sort, and manipulate lists.

The following code gives an example on how the List Class can be used.

#Initialize a new instance of the List<T> class that is empty
#and has the specified initial capacity of 10. The type of
#elements in the list will be strings.
$mylist = New-Object -TypeName System.Collections.Generic.List[System.String](10);

#Create a string containing some words for us to play with.
$fox="the quick brown fox jumps over the lazy dog";

#Split the words up and place them into an array.
$words=$fox.Split(' ');

#Show the capacity of the list object.
Write-Host "mylist has capacity $($mylist.Capacity)";

#Clear the object just before we use it.
$mylist.Clear();

#Loop through the array and place the words into the 'List' object.
foreach ($w in $words) {
    $mylist.Add($w);
}

#Show how many items we have in the 'List' object.
Write-Host "mylist has $($mylist.Count) items";

#See if we can find a fox in the list.
$searchWord="fox";
if ($mylist.Contains($searchWord)) {
   Write-Host "We have a $($searchWord) in the list";
} else {
   Write-Host "The $($searchWord) isn't around";
}

#List the words as entered into the list.
Write-Host "`nUnsorted list output";
$num=0;
$mylist.GetEnumerator() | Foreach-Object {
    Write-Host ("Word number {0} = {1}" -f ++$num, $_);
}

#Produce a sorted list of words.
Write-Host "`nSorted list output";
$num=0;
$mylist.GetEnumerator() | Sort-Object | Foreach-Object {
    Write-Host ("Word number {0} = {1}" -f ++$num, $_);
}

Lines 41-46 produced a sorted output to the console. The contents of mylist are not really sorted as we used the Sort-Object cmdlet to display the contents in a sorted order. If you really want to sort the contents of your list, then Sort() method can be used. i.e.


$mylist.Sort();

Posted in powershell | Tagged , | Leave a comment