Monday, July 29, 2019

Web Jea - setting it up in my enviroment.

Web JEA is a cool tool that lets you create a website interface to administrative tools written in Powershell.
I set it up in my environment, and maybe I missed instruction or something but I needed to do some additional setting on the system before I could get it to operate correctly.
One thing that was very important was to stop the DSC autoconfiguration. this drove me batty for an afternoon as changes kept reverting to site info for configuration. I didn't make the changes with the DSC process in mind, not realizing that the changes were prohibited to those files.  It would be nice if I had some more understanding of how to work with DSC. but that's the big tip of the blog.

I needed to add the following instructions to C:\Source\DSCDeploy.ps1

Append to C:\Source\DSCDeploy.ps1

STOP-DscConfiguration
New-LocalGroup -Group WebJea
Add-LocalGroupMember -Group Administrators -Member $MyData.AllNodes.AppPoolUserName
Import-Module ActiveDirectory
"IT Admins", "IT techs", "IT Mgmt", "IT Engineering" |
ForEach-Object {
    Get-ADGroup  $_ |
    ForEach-Object {
        Add-LocalGroupMember -Group webjea -Member $_.name -verbose }
}
Get-ADGroup "DEPT Leads" |
    ForEach-Object {
        Add-LocalGroupMember -Group webjea -Member $_.name
        }
Get-ADGroup "IT Engineering" |
    ForEach-Object {
        Add-LocalGroupMember -Group webjea -Member $_.name
        }
Get-LocalGroupMember -Group webjea

Friday, June 14, 2019

HTTPS Cert Expired and I don't care

Cert expiration is the bain of web administrators and Internet Web Properties.
use to be, you had to pay richly for the grand privilege of having a certificate on your website.
Now it just a matter of course.

Use this PowerShell incantation to set the "I Don't Care" on the certificate checking code.


[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }


Yes, I know it is not secure now, but I need to get to the site for testing or whatever, and I am willing to accept a connection to allow me to do what I need. 

* Use of course at your own risk. 

Enable Proxy server settings in PowerShell

proxy servers don't like you to go straight to the internet.

you get an error something like:

Invoke-WebRequest :
This Page Cannot Be Displayed
Authentication is required to access the Internet using this system. A valid user ID and password must be entered when prompted.

so you need to give this Powershell Incantation

#Proxy
$wc = New-Object Net.WebClient
    $wc.UseDefaultCredentials = $true
    $wc.Proxy.Credentials = $wc.Credentials

You can guess from this that you can actually set proxy credentials with this. But I haven't worked that out yet.

Web-request all TLS modes

I had fits and starts connecting to servers that had the TLS hardening put on them for web requests.
And a simple setting allowed you to connect to tls1.2 configured web servers.

However, since I was writing a script that could talk to any mode TLS server Like a normal web browser,  I experiment with my limited understanding of .NET request and came up with a short but sweet way to set it.

The I painfully discovered that if you set this more than 2 times, then webrequests would break.
So I added a check to see if it was set, so if this gets in a loop the access doesn't break.


#enable TLS*
if ([Net.ServicePointManager]::SecurityProtocol -ne
    ([Net.SecurityProtocolType].GetEnumNames() |
        ? { $_ -like "Tls*" }))
{
    [Net.ServicePointManager]::SecurityProtocol =
    ([Net.SecurityProtocolType].GetEnumNames() |
        ? { $_ -like "Tls*" }) }
br /> You can set a servers TLS and Crypto setting with:
  http://www.hass.de/content/setup-your-iis-ssl-perfect-forward-secrecy-and-tls-12
  By Alexander Hass
        at your own risk.

I modified his script to not disable any the TLS modes so This could be applied without risk to servers to fix access problems without creating a new problem for apps / scripts that can't ope with TLS ver 1&2
(Which is not to say some other archaic system might have a sezure with changing the criypto settings.

Friday, May 10, 2019

Start-Azure

This is a script to take control of the browser in logging into Microsoft Azure Portal.

I had the recurring irritant, that when I wanted to access my Azure Dashboard,   I had to go through 2 logins, and that is because I was using Chrome browser,  as it worked best in my environment...
and a proxy server login... it took a few steps and because of proxy server required yet another login.
Something not required on IE/Edge"

I needed a way to send keystrokes to the open window and control it that way.
So, I got out some Whip It up a tude,  and started playing in the shell, and searching with google.
(Google knows everything, ya just got to know how to ask.)
A Blog article by Massimo Santin, I found this on his blog.
a-simple-powershell-script-to-send-keys-to-an-application-windows/

Send-Keys.ps1
<#
.SYNOPSIS
Send a sequence of keys to an application window

.DESCRIPTION
This Send-Keys script send a sequence of keys to an application window.
To have more information about the key representation look at http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
(C)2013 Massimo A. Santin - Use it at your own risk.

.Source 
https://invista.wordpress.com/2013/08/16/a-simple-powershell-script-to-send-keys-to-an-application-windows/

.PARAMETER ApplicationTitle
The title of the application window

.PARAMETER Keys
The sequence of keys to send

.PARAMETER WaitTime
An optional number of seconds to wait after the sending of the keys

.EXAMPLE
Send-Keys "foobar - Notepad" "Hello world"

Send the sequence of keys "Hello world" to the application titled "foobar - Notepad".

.EXAMPLE
Send-Keys "foobar - Notepad" "Hello world" -WaitTime 5

Send the sequence of keys "Hello world" to the application titled "foobar - Notepad" 
and wait 5 seconds.

.EXAMPLE 
    New-Item foobar.txt -ItemType File; notepad foobar.txt ; Send-Keys "foobar - Notepad" "Hello world{ENTER}Ciao mondo{ENTER}" -WaitTime 1; Send-Keys "foobar - Notepad" "^s"

This command sequence creates a new text file called foobar.txt, opens the file using a notepad,
writes some text and saves the file using notepad.

.LINK
http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
#>
Function Send-Keys {
param (
    [Parameter(Mandatory=$True,Position=1)]
    [string]
    $ApplicationTitle,

    [Parameter(Mandatory=$True,Position=2)]
    [string]
    $Keys,

    [Parameter(Mandatory=$false)]
    [int] $WaitTime
    )

# load assembly cotaining class System.Windows.Forms.SendKeys
[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
#Add-Type -AssemblyName System.Windows.Forms

# add a C# class to access the WIN32 API SetForegroundWindow
Add-Type @"
    using System;
    using System.Runtime.InteropServices;
    public class StartActivateProgramClass {
        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
    }
"@

# get the applications with the specified title
$p = Get-Process | Where-Object { $_.MainWindowTitle -eq $ApplicationTitle }
if ($p) 
{
    # get the window handle of the first application
    $h = $p[0].MainWindowHandle
    # set the application to foreground
    [void] [StartActivateProgramClass]::SetForegroundWindow($h)

    # send the keys sequence
    # more info on MSDN at http://msdn.microsoft.com/en-us/library/System.Windows.Forms.SendKeys(v=vs.100).aspx
    [System.Windows.Forms.SendKeys]::SendWait($Keys)
    if ($WaitTime) 
    {
        Start-Sleep -Seconds $WaitTime
    }
}
}


So I went about utilizing this function to do what I needed, I compiled the information about the windows that needed to be open and what needed to be entered into the windows. and created this script.

start-azure.ps1
<#  
    .NOTES
    ===========================================================================
     Created on:    4/10/2019 6:53 PM
     Created by:    Richard Stoddart
     Organization:  Fabricam.com
     Filename:   start-azure.ps1    
    ===========================================================================
    .DESCRIPTION
        Open Azure session on workstation. 
#>

#Setup
#load function Send-Keys
. "$PSScriptRoot\Send-Keys.ps1"

$EmailFile = "$PSScriptRoot\Email.txt"
$CipherFile = "$PSScriptRoot\Cipher.txt"


#deal with email setting
# delete $EmailFile to restart this query. 

IF (!(Test-Path $EmailFile))
{
    read-host -Prompt "EMAIL File not found! Please Enter EMAIL:" |
    Out-File $EmailFile
}

$Email = Get-Content $EmailFile

#Deal with password cipher

# delete $cipherfile to restart this query. 
IF (!(Test-Path $CipherFile))
{
    read-host -Prompt "Password File not found! Please Enter new Password:" -AsSecureString |
    ConvertFrom-SecureString |
    Out-File $CipherFile
}

# https:portal.azure.com
& "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"  "https://portal.azure.com"
#Waiting for startup. 
$Loop = 100
While ($Loop -gt 1)
{
    If (((Get-Process | ? { $_.ProcessName -eq "chrome" } | 
? { $_.mainwindowtitle -like "Sign in*" }).mainwindowtitle)) { $loop = 0 }
    else { $loop-- }
    if ($loop -eq 1) { Return "timeout opening azure site" }
    Write-Host "." -NoNewline
    Start-Sleep -Seconds 1
}
"`nAzure login open, Proceed"
#enter login info
Send-Keys -ApplicationTitle "Sign in to Microsoft Azure - Google Chrome" -Keys "$email`r"
Start-Sleep -Seconds 2
Send-Keys -ApplicationTitle "Sign in to Microsoft Azure - Google Chrome" -Keys "`r"


#Proxy Server login section

#Waiting for proxy. 
$Loop = 100
While ($Loop -gt 1)
{
    If (
      ((Get-Process | ? { $_.ProcessName -eq "chrome" } |
      ? { $_.mainwindowtitle -like "https://gfs.private.fabricam.com*" }).mainwindowtitle)
     ) 
     { $loop = 0 }
    else { $loop-- }
    if ($loop -eq 1) { Return "timeout logging into proxy" }
    Write-Host "." -NoNewline
    Start-Sleep -Seconds 1
}

$GFSTitle = (Get-Process | ? { $_.ProcessName -eq "chrome" } |
    ? { $_.mainwindowtitle -like "https://gfs.private.fabricam.com*" }).mainwindowtitle

$Cipher = get-content $CipherFile | ConvertTo-SecureString
$Pass = (New-Object PSCredential "user", $Cipher).GetNetworkCredential().Password

Send-Keys -ApplicationTitle $GFSTitle -Keys "$ENV:USERDOMAIN\$EnV:USERNAME`t$Pass`r"

Clear-Variable Pass, Email


* Set the proxy server name to your environment Proxy server web name.

This is used in the include so it must be in the same DIR.

Once I worked the bugs out it, it works like a charm. and I created a Shortcut on the desktop to link to the script to go and open Azure for me.

It may take a little tweaking in your environment. Your proxy server may have a different name, and I did edit this sample to a fictitious company.

I did some password encryption to securely store the Proxy server password. To keep the security wonks off my case.


Wednesday, May 1, 2019

Powershell + Devops Global Summit 2019

I am here at the summit and its great!
YouTube: PowerShell Devops Summit report 1
The first day was opening keynote speeches

First up wall Will Anderson and he covered the welcome and introduction to the conference.
he did great with covering what we needed to know about the con.

then we got blown away by the powerhouses, Don Jones and Jeffry Snover.

Here is a link to my first video report.  It's going to be impromptu, no editing but I hope you enjoy it.

here is the first video3
LINK:  PowerShell Devops Summit report 1

LINK: PowerShell Devops Summit 2019 - report 2

LINK:   PowerShell Devops Summit 2019 report 3

LINK:  PowerShell Devops Summit 2019 report 4




Tuesday, January 8, 2019

IBM WebSphere MQ PowerShell SnapIn

I found myself responsible for the operation of some servers that use IBM WebSphere MQ.
Slowly over time, my manager thinking that another team was responsible for the operation of the software, and would provide all the technical support for the product. So he instructed me to stay hands off on the software. Just maintain the os and the IIS components. 

Well, for better or worse, the IBM software was fairly stable, but over time, issues like memory leaks required us to restart the web app pool. More issues came up demanded answers from management, and the support team that was to take care of WebSphere MQ dissolved quietly. While a few staff that new the product remained, they moved off to development products. Another engineer left the company. So I was left the SME on the product. So.. I had to become more familiar with the Product and to support the new engineer and the team that took over the MQ support for the system. I needed a health check for the product to help understand what it was configured and how it was performing. 
So did my research and I found that IBM had published a snapin for the product, and was still supporting it. I Know PowerShell, and that module was very priceless in figuring out what the configuration was doing. 

Here I share my experiences with installing Powershell Support for IBM WebSphere MQ.

The 32-bit installer is simple.
However, the 64-bit version is a bit cryptic.

The wonderful module that IBM provided can be found:
LINK: MO74: WebSphere MQ - Windows PowerShell Library

Install file in the zip.:
  • Unzip the downloaded file:  mo74_v2.0.1.zip to a work directory/folder on your target computer. 
  • Open the work folder, and switch to the sub folder/directory:  \mo74_v2.0.1.zip\mo74_v2.0.1\mo74_v2.0.1_x86_x64
  • RUN the installer: setup.exe

Follow the standard GUI install process. (AKA the forehead install. )

There is a directory created by default in:

  • C:\Program Files (x86)\IBM\PowerShell for WebSphere MQ

This contains files you need for 64 Bit support.
Now, WHY would you want 64-bit support???
Well, most servers these days are 64-bit, and the Remote Powershell stuff on a 64-bit computer uses the 64 bit Powershell version. and the Snapin installs in only the 32-bit version of PowerShell.

You can use this following PowerShell script to install the WebSphereMQ 64-bit support snapin.

Script:
$path = "c:\Program Files\WindowsPowerShell\Modules\WebSphereMQ\"

mkdir $path -Verbose -ErrorAction SilentlyContinue

COPY "C:\Program Files (x86)\IBM\PowerShell for WebSphere MQ*" $path

CD $path

"Change Dir to: $PWD"


$DLLS = GCI *.dll

$FWInstall =
    gci C:\Windows\Microsoft.NET\Framework64\v4.* `
        -Recurse -Filter "InstallUtil.exe"
    #Line wraped with backtick.
& $FWInstall.FullName $DLLS

#Save the current value in the $p variable.
$p = [Environment]::GetEnvironmentVariable("PSModulePath")

#Add the new path to the $p variable. Begin with a semi-colon separator.
$p += ";$PWD"

#Add the paths in $p to the PSModulePath value.
[Environment]::SetEnvironmentVariable("PSModulePath", $p)
* you can use this code and the contents of the dir and install as part of a server build script. 

The installer program provided with .NET is verbose and will tell you how the process of registering the DLL's goes. 

Snapin is loaded with the following:
Add-PSSnapIn IBM.PowerShell.WebSphereMQ

You can check to see if the commands have been added with the following command


Get-Command *WMQ*


>> How to use all these nifty new commands is Subject of another article.