Category Archives: Uncategorized

PowerShell: Use a Profile for ISE settings

The PowerShell profile is a .Ps1 startup script that runs when you first load the interactive script editor (ise). You can use it to load modules, set a default prompt and default directory, and to map abbreviations to longer command strings.

To see the location of the profile, you simply have to examine the $profile variable:

PS >$profile
 C:UsersLarryDocumentsWindowsPowerShellMicrosoft.PowerShellISE_profile.ps1

The profile can be opened like any other script.

To reload a profile after editing it, you simply need to invoke it using the ampersand “call operator”.

PS> & $profile

If you are reloading an already existing profile…then you may see lots of harmless errors as PS complains about settings that were already in place.

  • Here’s my current profile. It does three things:
  • Changes the prompt to PS>
  • Changes to my default working directory
  • Set an alias of gh for the get-help commandlet
  • Set an alias of np to start notepad++
# Define the powershell Prompt.
function prompt 
{ 
"PS>"
}

# Define the default working directory

Set-Location C:UsersLarryPowershell
PWD  # show the current working directory
# Set an alias for the Get-Help command. 
Set-Alias gh Get-Help
# Set an alias to run the Notepad++ editor 
Set-Alias -Name np -Value "C:Program Files (x86)Notepad++notepad++.exe"

The last command took some experimentation, but I can now type np followed by a file name to open the notepad++ editor with that file.

Powershell: Use the SmartyStreets API

SmartyStreets is an address validator for U.S. postal addresses.  Feed SmartyStreets an address, like “11 Church Street, Burlington VT” and, if the address is matchable with the official U.S. postal service address, it will be returned, including the 9 digit zip code.  The SmartyStreets API has some of the best API documentation. Here is the PowerShell  code to validate a single address.

<#Powershell Code to query SmartyStreets API 
Provide address validation for a single U.S. address submitted to the API
LK 11/12/2014 
#>

$Output=""

$Uri="https://api.smartystreets.com/street-address?"+
"street=11+Church+Street&"+
"city=Burlington&"+
"state=VT&"+
"auth-id=myauthid"+
"auth-token=myauth-token"

$Output=Invoke-RestMethod -Uri $Uri -ContentType application/json -Method Get 

$Output.delivery_line_1
$Output.last_line
$Output.metadata

Athe auth-id and auth-token are values that you obtain from the Smartystreets site, which validate your account.

The result of the code is placed in the variable $Output.

Running this program provides the following output, the two validated address lines, and a slew of meta-data related to the address, including the county, gps coordinates, etc.

11 Church St
 Burlington VT 05401-4417
record_type : S
 zip_type : Standard
 county_fips : 50007
 county_name : Chittenden
 carrier_route : C009
 congressional_district : AL
 rdi : Commercial
 elot_sequence : 0196
 elot_sort : A
 latitude : 44.47953
 longitude : -73.21282
 precision : Zip9
 time_zone : Eastern
 utc_offset : -5
 dst : True

You can see the returned fields by piping $Output to Get-Member  The delivery_line_1, and last_line contain the validated address with nine-digit zip code.

PS >$Output | Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name                   MemberType   Definition
 ----                   ----------   ----------
 Equals                 Method       bool Equals(System.Object obj)
 GetHashCode            Method       int GetHashCode()
 GetType                Method       type GetType()
 ToString               Method       string ToString()
 analysis               NoteProperty System.Management.Automation.PSCustomObject analysis=@{dpv_match_code=Y; dpv_footnotes=AA...
 candidate_index        NoteProperty System.Int32 candidate_index=0
 components             NoteProperty System.Management.Automation.PSCustomObject components=@{primary_number=11; street_name=C...
 delivery_line_1        NoteProperty System.String delivery_line_1=11 Church St
 delivery_point_barcode NoteProperty System.String delivery_point_barcode=054014417112
 input_index            NoteProperty System.Int32 input_index=0
 last_line              NoteProperty System.String last_line=Burlington VT 05401-4417
 metadata               NoteProperty System.Management.Automation.PSCustomObject metadata=@{record_type=S; zip_type=Standard; ...

Pass parameters to executables from the PS command line.

Working from within the PowerShell ise sometimes you still need to run an external editor to edit a text file. I use Notepad++ for this purpose and it is a pain to invoke it from within the command line and to pass the name of the file that I want to edit at the same time.  Here is how you can start NotePad++ by itself.

& "C:Program Files (x86)Notepad++notepad++.exe"

Note that the full command string is within double quotes, to accommodate the spaces in the folder names. Because the strings are quoted, we also need to to preface the string with the at “&” sign, which means “execute this….”

Now, typically I’ll have an existing text or html file that I already want to edit.  This can be appended to the command.

& "C:Program Files (x86)Notepad++notepad++.exe" winners.txt

Notepad++ will open multiple files in separate tabs that are passed to it when opening.

& "C:Program Files (x86)Notepad++notepad++.exe" winners.txt,loosers.txt

More details are in this article at Windows IT Pro.

Powershell: Basic text processing

Problem:  I’ve received two files of eMail addresses. These represent one group that were awarded a grant, and much larger group that were rejected. I’m going to call these two files winners.txt and losers.txt.

I want to end up with the following:
1. Eliminate invalid eMail addresses
2. Eliminate duplicate records in both files
3. Check to see that anyone in the winners file does not appear in the losers file.

Although I’ve received these as an Excel Spreadsheet, I’ll use Excel to write them out as comma-delimited text files. Maybe later I’ll figure out how to work with the Excel spreadsheet directly from Powershell.

After exporting the eMail addresses from Excel they are contained in two .csv files….comma delimited text with each field enclosed in quotes. There were a huge number of blank lines at the bottom of each file, which I’m assuming are a result of the Excel export.

Working with the winners.txt file:

1. Count the number of lines in the file:
Get-Content winners.txt | measure-object -Line

2. Eliminate the blank lines. These were lines that had an empty string enclosed in double-quotes followed by a carriage-return, line feed..
 (Get-Content winners.txt -Raw)`
.Replace( "`"`"`r`n" ,"" )| Set-Content winners.txt

3. Eliminate the rest of the quotes
 (Get-Content winners.txt -Raw).Replace( "`"" , "" ) `
| Set-Content winners.txt

4. Validate for the presence of an @ character in each line. (Ok, I know there are some more robust email format evaluation routines using regular expressions or even .NET objects, but I’m reserving those for another time. Right now, I’m assuming that if a line includes an at sign ‘@’ then I can work with it).

(Get-Content winners.txt) | select-string "@" `
| Set-Content winners.txt

5. Eliminate duplicate lines
$fn=winners.txt
( Get-Content $fn ) | sort | get-unique >$fn

Note that you have to sort the lines to be able to get-unique.

Having done the above four steps on the winners’ file, I repeated them with the losers’ file. Then I compared the two files to find lines that appeared in both files, (which of course meant that my winners’ eMail addresses were present in the loosers’ file.)

5. Find lines that appear in both files.
Compare-Object -DifferenceObject $winners `
-ReferenceObject $loosers `
-ExcludeDifferent 

It turns out that all of my winners eMail addresses appeared in the loosers file as well. I deleted these with a manual search and replace… (but that’s another PowerShell story to look up).

Notes:
1. The parentheses around Get-Content in a command act like they do when doing arithmetic. They instruct PS to execute those commands first. This is necessary when modifying the conents  of a file without creating an intermediary file to hold the contents.  The downside is that the file is read entirely into memory, so there may be implications with especially large files.

2. The line continuation character is a back-tick character, “`”.  It also serves as the escape character when you need to include a particular character as part of a search string. So, in the search string in step 1,Replace( “`”`”`r`n” ,”” ) means, replace any line that has “” as its contents.

3. Find the default printer
Get-WmiObject `
-Query " SELECT * FROM Win32_Printer WHERE Default= $true"

From <https://wordpress.com/post/78494701/4&gt;

PowerShell FTP Follow-up

This script is an attempt to automate a lengthy error-prone copying and configuration process that we do each week. If we do the process manually it can take anywhere from five to twenty minutes, and it tends to have various points of failure.  The piece below is actually just one portion of the process. The steps include: 

1. Get the name of a new folder to be created on the server
2. Get the name of the file to be copied into the new folder
3. Using the two new names, build a text file which contains commands that will be fed into PSFTP
4. Call PSFTP and run the commands in the text file.

This  PowerShell script uses Putty FTP to log into an FTP server, create a new folder, and copy a file to that folder from the local host. Note the the steps for making the folder and copying the file are contained in a Putty script called gwkprocess.scr. This secondary script is is used as input to the Putty program after Putty makes the connection.  Those steps are typical FTP steps: 

CD / topdirectory
MKDIR  /new directory
CD /newdirectory 
PUT myfile.png  


<# Powershell Scripted FTP
LK 10.30.2014 
Send a file to the eMail server via FTP.
Uses the Putty Secure FTP program PSFTP
#>


# $FTPFolder=’/home/web/html/store/images/fy2014/Kids-Shop’
# Note that the login credentials are in clear text! 

# Enter the new folder name here. 
$NewFolder = “20141101ks”

# The Picture file to be copied is located in 
# C:UsersLarryPowershell 
# and should be named, with the usual naming convention
$PicFile = “20141101ks-image.png”

#Note line wraps. 

#Build the Putty Script file 
“cd /home/web/html/store/images/fy2014/Kids-Shop”| Out-File -FilePath C:UsersLarryPowershellgwkprocess.scr -Encoding ascii

“mkdir $Newfolder” | Out-File -FilePath  C:UsersLarryPowershellgwkprocess.scr  -Encoding ascii -Append


“put $PicFile” | Out-File -FilePath  C:UsersLarryPowershellgwkprocess.scr  -Encoding ascii -Append

“ls” | Out-File -FilePath C:UsersLarryPowershellgwkprocess.scr  -Encoding ascii -Append


# Call the putty program 
.psftp myuser@192.168.214.103 -P 22 -pw mypassword -v -2 -b gwkprocess.scr

This starts PSFTP in the Powershell window, makes the connection and then executes the gwkprocess.scr  steps. It then closes the connection. If there is a problem, PSFTP will print a failure message, but clearly there is room for more error checking on the front end. 

The presumption is that the secondary script gets rebuilt with new file and folder names each time the script is run. Obviously, there are some refinements to be included, like  interactive data entry of the file and folder names.

PowerShell: Shorten Links with the Bit.ly API

Isn’t it annoying….you have actually go to a web site to shorten your URL!  Here’s how to do it in PowerShell, and you’ll get the shortened URL printed on the command line.

If you save this script in a folder, you can run it by navigating to the script, right-clicking and choosing “Run in PowerShell”.

# Generate shortened URL using the Bitly API 
# To set this up: 
# * You must create an account at Bit.ly, and obtain an $ 
# * authorization token. 
# * Verify your Bit.ly account with an eMail that Bitly 
# * sends to your account. 
# * Obtain an authorization token at: https://bitly.com/a/oauth_apps
# Paste the authorization token here…

$OAuthToken=”xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”

$Instructions = “You can paste a long URL into the command line by` right-clicking the mouse.`n”
$Instructions 
$LongURL= Read-Host “Enter or Paste in the Long URL”

# Make the call
$MyURL=Invoke-WebRequest `
-Uri https://api-ssl.bitly.com/v3/shorten `
-Body @{access_token=$OAuthToken;longURL=$LongURL} `
-Method Get

#Get the elements from the returned JSON 

$MyURLjson = $MyURL.Content | convertfrom-json 

# Print out the shortened URL 
$MyURLjson.data.url 

Pause

Powershell: Scripting FTP

Having spent some hours figuring out how to script an FTP transfer, I thought I’d describe my kludge. Maybe someone can suggest a more elegant way.  I’m trying to I’m connect to a FTP server on my Linux box to upload a file.
There are at least three approaches that can be taken:
1. Directly interact with .NET objects
2. Import a Powershell module for FTP
3. Use Powershell to manipulate a command line FTP program, such as the Putty Secure FTP program PSFTP.
I started with the second option recommended on TechNet. Looks great, and I thought that it was semi-official (being from Technet). I was unable to get a connection and I think it may be related to the fact that module apparently doesn’t support SFTP version 2.  There are a couple other quirks with the module… including the fact that the user name and password are passed to the command line as an object.  
By the way, both option 2 and 3 have the same name, PSFTP. 
Option 2 = Powershell FTP 
Option 3 = Putty Secure FTP 
So, I’m on to option 3.  This looks a little more promising.  One gotcha, however, is that calling Putty PSFTP from the Powershell ise, makes the connection but doesn’t return to show the PSFTP prompt. Here’s the command (so far) 
PS> .psftp myaccount@192.168.224.184 -p 22 -pw mypassword -v -2
This command shows that:
The psftp program is located in the current directory.
myaccount@192.168.224.184 – is the login account used for logging into the target machine
192.168.224.185 – is the IP address of the target machine
-p 22 – is port 22, used for Secure FTP
-pw is the password
-v is verbose (upon execution it returns all the steps of the login
-2 is SSL version 2.
Running this from the command line in the ISE gives the following:
  .psftp : Looking up host “192.168.214.184”
At line:1 char:1
+ .psftp myaccount@192.168.224.184 -P 22 -pw mypassword -v -2
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Looking up host “192.168.224.184”:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
Connecting to 192.168.224.184 port 22
We claim version: SSH-2.0-PuTTY_Release_0.63
Server version: SSH-2.0-OpenSSH_3.8.1p1
Using SSH protocol version 2
Doing Diffie-Hellman group exchange
Doing Diffie-Hellman key exchange with hash SHA-1
Host key fingerprint is:
ssh-rsa 1024 ce:ec:0d:c2:90:ab:5e:87:12:bf:ba:f9:78:77:89:fb
Initialised AES-256 SDCTR client->server encryption
Initialised HMAC-SHA1 client->server MAC algorithm
Initialised AES-256 SDCTR server->client encryption
Initialised HMAC-SHA1 server->client MAC algorithm
Using username “myaccount”.
Attempting keyboard-interactive authentication
Access granted
Opening session as main channel
Opened main channel
Started a shell/command
Connected to 192.168.214.103
Remote working directory is /ftproot
PS >
If you run this from the ise, it returns the PS command as shown.  
If you run this from a regular powershell command session, it will keep you in the PSFTP session, and you can run use the usual FTP commands….like CD, etc. 
In either case, the way Putty FTP can execute scripted commands is that the script has to live in a separate batch file that is called from the command line.  There doesn’t appear to be a  way to pass commands from Powershell to a running Putty SFTP session.  (hmm.. really?) 
Additioanal points: 
1. I might be able to configure the FTP server running on the Linux box to accept the connection from the PowerShell FTP module. I haven’t investigated that possibility but presumably it would be less secure in terms of encryption.

2. The script above has the name and password in clear text.  Not a best practice. 
3. Various versions of FTP are described on this page.  

Brightpearl API Part IV: Assessment and Plan

Part IV

I’ve been working through a process using the REST web API provided by the Brightpearl Inventory and Customer Relationship Management System. I think we’re about one-third through the process, and I wanted to take stock and plan what the next steps are. I’m mindful of the answer to the question of “how do you eat an elephant?” which is “one bite at a time”.

  • Complete the queries
  • Parse the JSON responses 
  • Convert the results to a .DBF file. 
Since I’m confident about sending queries to the system, I think the next piece to work on is how to parse the JSON output, so that the resulting string of fields and data can be inserted into a database program.  Ultimately, we’re looking to transform the JSON output shown in Part I into a series of fields and data. 
order ID Integer
orderTypeID Integer
contactID Integer
orderStatusID Integer
orderStockStatusID Integer
createdOn Timestamp
createByID Integer
orderPaymentStatusID Integer

Brightpearl API Part II What is JSON?

Part II of a series about working with web APIs. 
 
Part I is located here
 
JSON (JavaScript Object Notation) is described at http://www.json.org/. It is a simple data interchange language which depends on two fundamental data structures:
Object: An unordered set of name / value pairs
Objects are delineated by curly brackets. Each name /value pair is separated by a colon, and pairs are separated by a comma.
Array: An ordered collection of  of values
Values in an array can be almost any data type, including string, number, array, true, false, null, or object.
Arrays are delineated by brackets. Array elements are separated by a comma.
So,  when we’re passing in the authorization credentials for our Brightpearl API, we’re passing in a nested set of name/value pairs as a single object:
{
    apiAccountCredentials:{
        emailAddress:”myname@mydomain.com”,
        password:”mypassword”
    }
}
Brightpearl returns query results as JSON as well. The first part of a the result is the description of the data….the second part is the actual data. (See Part 1 of this series for the full example).
The JSON.org page has links to JSON libraries for a plethora of programming languages and databases. While not listed on the page there is also a JSON module for FileMaker.  For mySQL there is a discussion of a couple ways of formatting the output of a mySQL query into JSON using Ruby, PHP, or using PHPmyAdmin.

Tech Friday: FileMaker Resources

Random FileMaker-related resources: 

1. You can create an alternative icon for FileMaker 13. When you have multiple FileMaker versions installed, it sometimes is difficult to distinguish between them. FM12 and FM13 have virtually identical icons with the same color schemes. Here are alternative icons that can be installed, for both Win and Mac from HomeBase Software. HomeBase has a ton of of technical information on their web site.

2. In support of a project to integrate SmartyStreets with FileMaker, I’ve been doing some additional research on JSON, (Javascript Object Notation), which is a simplified version of XML.

3. Coding Standards for FileMaker

4. Modular FileMaker: is shared library of FileMaker functions. There are huge community-developed libraries for other languages such as PHP and Python. These folks are attempting a similar idea for FM. I’ve downloaded their JSON module, and am experimenting with it. Other examples include a nifty SQL query generator, and and another interface to Mailchimp.

Custom Functions are a way of adding small chunks of user-defined code that can be called within a FileMaker script. Brian Dunning is the guru here and curates the largest library of custom FM functions on the web. He also has sample data sets available for the U.S., Austria, Canada, and the UK. Five hundred records are free, and a million records are available for ten bucks.

5. If you need a 100,000 records or so, you could also download the database of public and private schools available at the National Center for Education Statistics. This includes demographic data as well as mailing and location addresses for schools. The data is fun to play around with. You can give yourself some sample exercises in FileMaker. For example:

6. What percentage of public school students are eligible for free or reduced lunch in your state? It is 38% in mine. Poking around in some other states, it looks like that isn’t unusual; in many states it is 40-60% or more. The lunch program is often considered a proxy for the family poverty rate. But maybe that’s another discussion.