Thursday, November 10, 2016

Powershell - print all files from a directory

This likely doesn't come up very often for folks these days, but someone out there may appreciate this script.

This script came from a business need to print off a few hundred text files from a directory on the network. With windows printers, you can drag files to a printer and "drop" them into it, to be able to print a lot of files at once, but there's still quite a bit of clicking involved.

This script when run, will prompt for selecting a directory from mapped drives on the machine, it will then print all contents of that directory to the default printer for the machine.

I could get fancier with this, but don't feel a need to as yet. Hopefully this may serve to help others as is / with some minor modifications.

**********Begin script***********

cls
echo " "
echo " "
write-host "Would you like to Print all the Txt files from a directory?" -foregroundcolor RED
echo " "
$Selection = read-host "Type y or n:"
echo " "
cls
If ($Selection -eq "y")
{
cls
Write-Host "Select where to pull the Txt files from..." -ForegroundColor yellow
function Read-FolderBrowserDialog([string]$Message, [string]$InitialDirectory)
{
$app = New-Object -ComObject Shell.Application
$folder = $app.BrowseForFolder(0, $Message, 0, $InitialDirectory)
if ($folder) { return $folder.Self.Path } else { return '' }
}
$directory = Read-FolderBrowserDialog ("Select the folder to print Txt files from","C:\")
$PrintFiles = Get-childItem $directory
ForEach ($PrintFile in $PrintFiles)
{
Start-Process -FilePath "$directory\$PrintFile" -Verb Print -PassThru |%{sleep 5;$_}|kill
echo " "
write-host "Printing $PrintFile..." -foregroundcolor Green
echo " "
}
echo " "
Write-host "All files from the selected directory have been Printed" -foregroundcolor Green
echo " "
read-host "Press enter to exit:"
}
ELSE
{
echo " "
write-host "You chose no, this script is exiting..."
echo " "
read-host "press enter to exit:"
}

**********End Script*******************

Tuesday, July 26, 2016

Powershell - Logon hours value comparisons

Time to post an update to my widely un-read blog. :)

I had a case where management was requesting a check on the LogonHours value for staff members, in particular they wanted to know specific users who had a specific logonhours setup, but they also wanted to track the staff who either had no logonhours config, or could logon at all hours.

A quick google will bring up many many hits about how to user powershell to "SET" your logonhours values, and there's a really nice script from Richard Mueller "http://www.rlmueller.net/PowerShell/PSAllUsersLogonHours.txt" that can be used to make a report of current settings.

But there was nothing I could personally find regarding "comparing" / or really "confirming" that logon hours are set as management desires. This value in AD is stored oddly, so many scripts devolve into trying to parse the data apart into more readable formats . .that's all well and good, but a waste of time for my purposes. So I decided I needed to find my own way on this . .

I will post my finished script shortly, but want to first clarify the steps I used:

$Default = get-aduser BaseUser -properties *
$DefaultCheck = $Default.logonhours
By breaking variables out in the above manner, we get a variable which is specifically a logonhours value for a user account we want to use as baseline for comparisons in the script. (Note that BaseUser should be the samaccount name you want to check against in AD.)
 Again, lots of folks want to break down this data into a readable format . .that's great, but I don't honestly care, I want to compare a 'correct' setting against other accounts, and build a report, to do that....:

$Compare1 = "$Userhours" -match "$DefaultCheck"
More variables, but this line is our "comparison" by using -match. The return is a "True" "False" which can be further coded against. (Note $Userhours in the above case is a variable similar to $DefaultCheck, it's the user logon values we've pulled from AD and want to compare to our baseline value).

So with the above clarified, the remaining logic for the script is:


  • Identify the AD accounts in AD to be used for LogonHour comparisons.
  • Decide how you want the data reported.
For my particular case, my management had the following requests for the report:
  • list the user, list the user's manager, list the logon hours setup.
  • a spreadsheet would be nice.
For my LogonHours comparisons, I had:
  • 1 user logonhour value that could be used as my Corporate baseline.
  • 1 user logonhour value that could be used as my baseline for AllHours access.
  • a catch routine for tracking users that had "NULL" as their logonhours value.
    • this means it was never defined in AD, and is effectively "AllHours access".
  • a catch group for tracking users that didn't match any of the above for their logonhours value.
For the Excel file report generation:
  • I tend to favor spreadsheets with autoformatting, in order to get such an output from my scripts I will often place a call to a VBS subroutine from: http://jeffkinzer.blogspot.com/2010/06/vbscript-to-convert-csv-to-xlsx.html
    • Jeff's very handy "csv_to_excel.vbs" can be easily called from within powershell to create autoformatted spreadsheets. 
The below script, will require a few edits to work in another environment, so pay attention to variable declarations. And as always, use at your own risk . .TEST TEST TEST.

Powershell script example:



Import-module activedirectory

#define variables for reports
$Report = "c:\Reports\Fulllist.txt"
$Nulls = "c:\Reports\Users-with-Null.txt"

#define logon hours results to query against
$Default = get-aduser UserNameVariable -properties *
$DefaultCheck = $Default.logonhours
$Allhours = get-aduser UserNameVariable -properties *
$AllhoursCheck = $Allhours.logonhours

#Pull user domain list
$Users = get-aduser -filter 'enabled -eq $true' -properties * -searchbase "LDAP domain search string variable for example DC=,DC=,DC=com"

#Prep reports with data column names
echo "Name ; LogonHours ; Manager" >>$Report

#Sort through results
ForEach ($User in $Users)
{
$Name = $user.name
$UserHours = $user.logonhours
$Manager = $user.Manager
#Check if logon hours is Null or not
If ($user.logonhours -eq $Null)
{
If ($Manager -eq $Null)
{
echo "$Name ; NotSet ; NotSet">>$Report
}
ELSE
{
$ManQuery = get-aduser $Manager
$ManName = $ManQuery.Name
echo "$Name ; NotSet ; $Manname">>$Report
}
}
ELSE
{
#Compare users logon hours with default.
$Compare1 = "$Userhours" -match "$DefaultCheck"
If ($Compare1 -eq $True)
{
If ($Manager -eq $Null)
{
echo "$Name ; Default ; NotSet">>$Report
}
ELSE
{
$ManQuery = get-aduser $Manager
$ManName = $ManQuery.Name
echo "$Name ; Default ; $Manname">>$Report
}
}
#Computer users logon hours with All hours authorization.
$Compare2 = "$Userhours" -match "$AllhoursCheck"
If ($Compare2 -eq $True)
{
If ($Manager -eq $Null)
{
echo "$Name ; AllHours ; NotSet">>$Report
}
ELSE
{
$ManQuery = get-aduser $Manager
$ManName = $ManQuery.Name
echo "$Name ; AllHours ; $Manname">>$Report
}
}
ELSEIF ($Compare1 -eq $False)
{
If ($Manager -eq $Null)
{
echo "$Name ; Variant ; NotSet">>$Report
}
ELSE
{
$ManQuery = get-aduser $Manager
$ManName = $ManQuery.Name
echo "$Name ; Variant ; $Manname">>$Report
}
}
}
}

write-host "report generation completed"
write-host "converting to XLSX"
$CSV = "c:\reports\Logonhours.csv"
$XLSX = "c:\reports\LogonHours.xlsx"

import-csv $Report -delimiter ";" | export-csv $csv -NoTypeInformation
$vbscript = "c:\csv-convert\csv_to_excel.vbs"
& $vbscript $Csv $xlsx
timeout /t 5 /nobreak
Remove-item $CSV -ea silentlycontinue
exit