Friday, July 29, 2016

Free eBooks from Microsoft

I just found out that Eric Ligman, Microsoft Director of Sales Excellence (whatever that is) is giving away a TON of free eBooks.  Head over to this site for the steaming poop: https://blogs.msdn.microsoft.com/mssmallbiz/2016/07/10/free-thats-right-im-giving-away-millions-of-free-microsoft-ebooks-again-including-windows-10-office-365-office-2016-power-bi-azure-windows-8-1-office-2013-sharepoint-2016-sha/

Now, one thing you will note is that you can either click on each eBook individually, or you can play leap-frog and click the "Download-All" button just to be hit with a "list" of the links.  A few folks posted complaints about that and so far no one has posted any real solution... except for me that is.

If you head over there, and it's been published, you'll see a little PowerShell script I whipped up and posted as a comment.  That script grabs the "list" and bulk downloads all the eBooks to a new folder on C:\ called "ebooks".  It's pretty straight forward. I'll repost it here since it could very well be usefull for many other things.

Clear-Host
#requires -version 3.0
$ErrorActionPreference = "SilentlyContinue"
If (!(Test-Path -Path "C:\eBooks")){New-Item -ItemType Directory -Force -Path "C:\eBooks" -Confirm:$false | Out-Null}
set-location "c:\eBooks"
$Source = "http://ligman.me/29zpthb"
$List = ((Invoke-WebRequest $Source) -split '[\r\n]') |? {$_}

Foreach ($URL in $List){
     Write-Host $URL -ForegroundColor Cyan
     $WebClientObject = New-Object System.Net.WebClient
     $WebRequest = [System.Net.WebRequest]::create($URL)
     $WebResponse = $WebRequest.GetResponse()
     $ActualDownloadURL = $WebResponse.ResponseUri.AbsoluteUri
     $ObjectProperties = @{'Shortened URL' = $URL;'Actual URL' = $ActualDownloadURL}
     $ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
     $WebResponse.Close()
     $FullURL = $ResultsObject.'Actual URL'
     Write-Host 'Target URL : '$FullURL
     $Count = ($FullUrl.ToCharArray() | Where-Object {$_ -eq '/'} | Measure-Object).Count
     $FileName = ($FullURL.Split("/")[$Count]) -replace "%20"," "
     Write-Host 'Downloading: '$FileName
     Invoke-WebRequest $URL -OutFile "C:\eBooks\$FileName"
     Write-Host "--------------------------------"
}

Write-Host "--- COMPLETED ---" -ForegroundColor Red


Tuesday, March 8, 2016

Wyse thin client terminal configuration inventory

If you work with thin clients this may come in handy.  I had a need to gather the configuration inventory from all of our Wyse C50LE terminals.  We have two sites and separate Wyse device manager servers.  The entire environment was set up before my time so I haven't done too much with it.

This script will access the C: drives of one or more servers and look in the default config file path for INI files.  It reads them, parses them, and drops them in a spreadsheet.  Change the targets variable to include whatever servers you need.

The resulting spreadsheet is saved in the same folder as the script.

<#==============================================================================
         File Name : Wyse-Config-Inventory.ps1
   Original Author : Kenneth C. Mazie
                   :
       Description : This script will query multiple Wyse Client Manager servers,
                   : detect, read, parse, and populate an Excel spreadsheet with the
                   : settings in all located config files.  The spreadsheet headers
                   : are dynamically generated and updated to add new entries as
                      : they are found
                   :
         Arguments : Named commandline parameters:  (all are optional)
                   :   "-console" - Displays console output during run. 
                      :   "-debug" - Switches email recipient and some criteria.
                   :
               Notes : None
                   :  
          Warnings : None
                   :
             Legal : Public Domain. Modify and redistribute freely. No rights reserved.
                   : SCRIPT PROVIDED "AS IS" WITHOUT WARRANTIES OR GUARANTEES OF
                   : ANY KIND. USE AT YOUR OWN RISK. NO TECHNICAL SUPPORT PROVIDED.
                   :
           Credits : Code snippets and/or ideas came from many sources around the web.
                   :
    Last Update by : Kenneth C. Mazie (email kcmjr AT kcmjr.com for comments or to report bugs)
   Version History : v1.0 - 02-03-16 - Original
    Change History : v1.1 - 00-00-00 -
                      :
#===============================================================================#>
#requires -version 3.0

Clear-Host
Param (
  [bool]$Debug = $false,
  [bool]$Console = $false
)

clear-host
$ErrorActionPreference = "silentlycontinue"
If ($Debug){$Script:Debug = $True}
If ($Console){$Script:Console = $True}
If ($Log){$Script:Log = $True}
$Files = ""
$Today =  Get-Date -Format ("MM/dd/yyyy").tostring()
$MissingType = [System.Type]::Missing

$TargetPath = "\c$\inetpub\ftproot\Wyse\wlx\*.ini"
$Targets = @(
     "wdm-server1",
     "wdm-server2"
)   

$Excel = New-Object -ComObject Excel.Application
If ($Script:Console -or $Script:Debug){
     $Excel.visible = $True
     $Excel.DisplayAlerts = $true
     $Excel.ScreenUpdating = $true
     $Excel.UserControl = $true
     $Excel.Interactive = $true
}Else{
     $Excel.visible = $False
     $Excel.DisplayAlerts = $false
     $Excel.ScreenUpdating = $false
     $Excel.UserControl = $false
     $Excel.Interactive = $false
}

$Workbook = $Excel.Workbooks.Add()
For ($C=1;$C -lt ($Targets.count+1);$C++){
     $WS = $workbook.Sheets.Item($C)
     $WS.activate()    
     $WS.name = $Targets[($C-1)]
}

Foreach ($Server in $Targets){
     If ($Script:Console){Write-host "-------- Target Server: $Server --------" -ForegroundColor Yellow}
     If ($Script:Console){Write-host "Full Path: \\$Server$TargetPath" -ForegroundColor Cyan }
     $FileList = Get-ChildItem -Path "\\$Server$TargetPath"
     $Worksheet = $Workbook.Sheets.Item($Server)
     $Worksheet.Activate()
     $Worksheet.Rows.Item("2:2").Select()
     $WorkSheet.application.activewindow.freezepanes = $true
     $Worksheet.Cells.Item(1,1).Select()
     $WorkSheet.Cells.Item(1,1) = "MAC Address"
     $Row = 2
     ForEach ($ConfigFile in $FileList){
          $FileName = ($ConfigFile.ToString()).split("\")[8]
          $ConfigFile | Get-Member
          If ($Script:Console){Write-host "------- Processing: $FileName -------" -ForegroundColor Magenta }
          $Col = 1
          $Filtered = @()
          $Script:LineItem = ""
          $InputFile =  Get-Content $Script:ConfigFile
          $Target = ($Script:ConfigFile).name.Split(".")[0]
          ForEach ($Script:LineItem in $InputFile){
              If ($Script:LineItem -match "="){
                   $Filtered += $Script:LineItem
              }
          }
          $WorkSheet.Cells.Item(1,1).entireRow.font.bold = $True
          $WorkSheet.Cells.Item($Row,1) = $Target
          If ($Script:Console){Write-host "Line Count      :"$Filtered.count}
          $TotalColumns = $Filtered.count
          if ($Col -gt $TotalColumns ){
              If ($Script:Console){Write-host "TERMINATED" -ForegroundColor Red}
              break;break;break
          }
          ForEach ($Script:LineItem in $Filtered){
              If ($Script:Console){Write-host "---------- Line Item Loop ----------" -ForegroundColor Magenta}
              If ($Script:Console){Write-host "Line Item       :"$Script:LineItem -ForegroundColor Cyan}
              $Property = $Script:LineItem.Split("=")[0]
              $Value = $Script:LineItem.Split("=")[1]
              If ($Script:Console){Write-host "Line Property   :"$Property -ForegroundColor Cyan}
              If ($Script:Console){Write-host "Line Value      :"$Value -ForegroundColor Cyan}
              If ($Script:Console){Write-host "Spreadsheet Row :"$Row -ForegroundColor Cyan}
              $RowOneRange = '"A2","A'+($Filtered.count+1)+'"'
              $WorkSheet.Cells.Item($Row,1) = $Target
         
              $Count = 1        
              $Col = 2
              $Found = $False
              while ($Count -le ($Filtered.count+1)){
                   If ($Script:Console){Write-host "------- Dynamic Column Loop -------" -ForegroundColor Magenta }
                   $Range = $Worksheet.Range("A1").EntireRow
                   $Search = $Range.find($Property,[Type]::Missing,[Type]::Missing,1)
                   if ($search -eq $null) {
                        $xlCellTypeLastCell = 11
                        $LastCol = $WorkSheet.UsedRange
                        $lastCell = $LastCol.SpecialCells($xlCellTypeLastCell)
                        $newcol = $lastCell.column +1
                        If ($Script:Console){Write-host "NULL search result up to column"$lastCell.column.ToString() -ForegroundColor Yellow}
                        If ($Script:Console){Write-host "Adding NEW column"$lastCell.column.ToString()"header..." -ForegroundColor Green}
                        $WorkSheet.Cells.Item(1,$newcol) = $Property
                        If ($Script:Console){Write-host 'Adding VALUE to row'$Row' column'($NewCol-1)'...' -ForegroundColor Green}
                        $WorkSheet.Cells.Item($Row,$newcol) = $Value
                        $Count ++
                        $Col++
                        break
                   }Else{
                        If ($Script:Console){Write-host 'Located PROPERTY at column'$Lastcell.Column.ToString() -ForegroundColor Yellow}
                        If ($Script:Console){Write-host 'Adding VALUE to row'$Row' column'($NewCol-1)'...' -ForegroundColor Green}
                        $WorkSheet.Cells.Item($Row,$Search.Column) = $Value
                        $Count ++
                        $Col++
                        break
                   }
                   If ($Script:Console){Write-host "---- Exiting Dynamic Column Loop ----" -ForegroundColor Magenta }
              }
         
              $Resize = $WorkSheet.UsedRange
              [void]$Resize.EntireColumn.AutoFit()
              If ($Script:Console){Write-host "------ Exiting Line Item loop ------" -ForegroundColor Magenta}    
          }
     $Row++
     }   
}

$SaveFile = "$PSScriptRoot\WyseInventory-{0:dd-MM-yyyy_HHmm}.xlsx" -f (Get-Date#--[ Places a date stamped spreadsheet in the script folder ]------
$Workbook.SaveAs($SaveFile)

$Excel.Quit()
$Excel = $Null
[void][gc]::Collect()
[void][gc]::WaitForPendingFinalizers()

If ($Script:Console){Write-host "`n--- Completed ---" -ForegroundColor Red}