PowerShell: Touch files

That is, in the unix sense of the term – updating files with a Now-type timestamp. Take this group of files with different datetime stamps:

touchFile01

In fact the dates don’t differ as much as I would have liked, but no matter. Let’s say we want to get to this:

touchFile02

This is a command to get there:

(gci C:\Perl) | ForEach-Object {$_.LastWriteTime = Get-Date}

, as you see here:

touchFile03

 

 

 

Advertisements

PowerShell: XML editing continued

This shows that in editing XML in PowerShell, if you assume that there is a single instance of an element, and there is more, then you get a very misleading error.

Simple piece of XML:

PSXml01

A few lines to update the firstName value:

PSXml02

All fine:

PSXml03

Now add in another record to the original file:

PSXml04

Run the same command again:

PSXml02

This time…

PSXml05

Actually as the contrast is poor, this is the error:

The property ‘firstName’ cannot be found on this object. Verify that the property exists and can be set.
At line:3 char:1
+ $xml.students.student.firstName = “Harry”
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException

The claim that ‘firstName’ might not exist is clearly wrong, but it is our/my own fault for being sloppy.

If we are now more precise about the record we are looking for:

PSXml06

, we get this…

PSXml07

We can do the update in 1 line…

PSXml08

, and now the file is updated OK:

PSXml09

Pastebin here here

Adding new elements with attributes

Using the state just now of the file as our starting point…

PSXml09

, this will only create a new record if that id (103) does not already exist…

PSXml10

pastebin

, giving this on the next execution, and all executions after that (i.e. the Rebecca rows):

PSXml11

pastebin

Security: OWASP and O-Saft

OSaft17

The goal: to display security vulnerabilities in the environment of the target machine:

OSaft16

Documentation.

Main site here.  Note that it is part of OWASP

OSaft01

OSaft02

Installation

OSaft09

Dependencies

A Perl distribution

Given the choice, maybe pick Strawberry Perl rather than e.g. ActivePerl, as the former seems to make it much easier to run OpenSsl, and it’s designed for Windows.. whatever that means in practice.

stPerl01

stPerl02

stPerl04

stPerl06

Test the basics

stPerl07

stPerl08

stPerl09

stPerl10

perl \perl_tests\hello_world.pl

stPerl11

Now over to the O-Saft section

Go to the https://www.owasp.org/index.php/O-Saft I referenced earlier and download as per the screenshot above.

Now that comes down as a file like this..

osafts01

So drill in and keep unzipping until you get to this level below o-saft.tar:

OSaft10

, and then move all that to a folder osaft, and delete the file I’ve highlighted below:

OSaft11

Then go to an administrator prompt and type

OSaft12

So now we start to get stuff. The red flags are the combinations of yes (i.e. I support on my machine ), and especially low or medium. Can we find any bad ones? Why yes…

OSaft13

Rather than plough through the file, much better to get PowerShell to parse it (yes Perl did occur to me, but you can have too many script languages). Our first test could just be for the yes/weak combinations. For that, let’s:

  • get the O-Saft output into a text file (as I don’t think I can get the perl directly into a variable)
  • move that text file into a variable
  • walk the variable, outputting (case-insensitive) [yes(tab)weak] matches

Which gives this (on my Windows 10 laptop – the first command takes about 15 seconds):

perl o-saft.pl +check localhost > .\osaft.txt
$warnings = Get-Content -Path .\osaft.txt
$warnings  | Where-Object {$_ -match 'yes[\t]weak'}

OSaft14

Are there any other bad combinations?

$warnings | Where-Object {$_ -match 'yes[\t]weak' -or $_ -match 'yes[\t]medium' -or $_ -match 'yes[\t]medium'}

OSaft15

No. However there is clearly repetition, so let’s reduce to unique combinations (and I am not bringing out under which particular protocols we are weak – for now we have to scan the file for the detail (osaft.txt in this example)).

$warnings | Where-Object {$_ -match 'yes[\t]weak' -or $_ -match 'yes[\t]medium' -or $_ -match 'yes[\t]low'} | select -Unique

OSaft16

And finally, this person deserves a call-out for their useful summary of Regex in PowerShell: http://ss64.com/ps/syntax-regex.html

fin

 Well, of that section. And then there’s OpenSsl:

OpenSsl01

Can’t find the config file, certainly not in that location. OK – set the system envvar to hold it:
OpenSsl02

OpenSsl03

OpenSsl04

Now we can do other stuff. This looks handy around OpenSsl examples.

PowerShell: basic Desired State Configuration (DSC)

This shows a basic config…

, which I have adapted for my Windows 10 box. Note ref Kerberos etc objections, you will also need to look at this.

Some history from the PowerShell session lest I forget:

Get-DscResource service -Syntax
Get-Item -Path WSMan:\localhost\Client\TrustedHosts
$cred = Get-Credential
Set-Item -Path WSMan:\localhost\Client\TrustedHosts -Value ‘DEN-I7’
$sess = New-PSSession -ComputerName DEN-I7
$sess = New-PSSession -ComputerName DEN-I7 -Credential $cred
C:\temp\BasicInstall.ps1

, where last line is this:

dsc01

Configuration BasicDscConfig
{
Node “DEN-I7” {
WindowsFeature NetFramework35Core {
Name = “NET-Framework-Core”
Ensure = “Present”
}

WindowsFeature NetFramework45Core {
Name = “NET-Framework-45-Core”
Ensure = “Present”
}

WindowsFeature ASP {
Ensure = “Present”
Name = “Web-Asp-Net45”
}
}
}

BasicDscConfig -InstanceName “DEN-I7”
Start-DscConfiguration -Path .\BasicDscConfig -Wait -Verbose -Force

#http://blogs.technet.com/b/privatecloud/archive/2013/08/30/introducing-powershell-desired-state-configuration-dsc.aspx

dsc02

Following a reboot after unsetting .Net 3.5 and 4.6 (sic), I tried again, and this time go this:

dsc03

So because this is a client-type machine, it won’t accept these particular Features from DSC.

Let’s see what happens if I more modestly just try to create a folder (I’ll delete the MOF files first)

Configuration BasicDscConfig
{
Node “DEN-I7” {
<# WindowsFeature NetFramework35Core { Name = “NET-Framework-Core” Ensure = “Present” } WindowsFeature NetFramework45Core { Name = “NET-Framework-45-Core” Ensure = “Present” } WindowsFeature ASP { Ensure = “Present” Name = “Web-Asp-Net45” } #>
File MyRandomDir {
DestinationPath = “c:\temp3\andMore”
Type = “Directory”
Recurse = $false
}
}
}

BasicDscConfig -InstanceName “DEN-I7”
Start-DscConfiguration -Path .\BasicDscConfig -Wait -Verbose -Force

#http://blogs.technet.com/b/privatecloud/archive/2013/08/30/introducing-powershell-desired-state-configuration-dsc.aspx
#https://technet.microsoft.com/en-us/library/dn282129.aspx

1

dsc04

2

dsc05

3

dsc06

4

PowerShell: web scraping

This is useful.

Because I want to get a bunch say of html table cell entries into an object. So this takes you a lot of the way there. Start out by grabbing the site into an object:

$apressBooks = Invoke-WebRequest -Uri "http://www.apress.com/microsoft/net-framework?limit=all"

These are the members:

WebRequest01

From there you can grab e.g. the links:

$links = $apressBooks.Links

WebRequest02

 

And you can get the hrefs from there (or do it all in 1 go of course):

$links.href

WebRequest03

 

WebRequest04Still a way to go but promising.

WebRequest05

 

 

 

 

PowerShell: deleting file records based on a condition

Given a file like this, where the second column is [Gender] and the third column is [Human], give me only rows which are [F](offset 20 from 0 – note it is zero and not 1) and [Human] (offset 30). Write the result to a file [HumanFemales.txt].

Dennis M Y
Jan F Y
Emma F Y
Bonzo M N

Names01

This reads the source file content into a variable, counts the records, filters the records based on the condition into an array, and writes the array to a file:

$data = Get-Content -Path C:\temp\names.txt
$data.Count
$filteredData = @()
$data | % {if ($_[19] -eq "F" -and $_[29] -eq "Y") { $filteredData += $_} }
$filteredData.Count
$filteredData | Out-File -FilePath c:\temp\HumanFemales.txt
gc C:\temp\HumanFemales.txt

WriteFile01

WriteFile02

For a file of about 50,000 records on a good I7 box, the records take about 3 minutes to write to the array, uses (depending on the record length) about 1GB of memory, and takes about 5 seconds to write to disk.