Bash Execute Script At Specific Time Without Cron


#Set Execution time to 3:15:01 PM

while true; do
    #Convert Execution Time to Epoch
    GoalTime=$(date -d "$TimeToExecute" +"%s")
    #Get epoch of 12:00:00 AM
    BaseTime=$(date -d "00:00:00" +"%s")
    #Get the current epoch
    CurrentTime=$(date +"%s")
    #Get the epoch difference between the goal execution time and current time
    TimeDifference=$(date -d "0 $GoalTime seconds - $CurrentTime seconds" +"%s")
    #Get the difference between the "TimeDifference" and 12:00:00 AM 
    BaseDifference=$(( $BaseTime -$TimeDifference ))
    #If BaseDifference is equal to zero then execute script
    if [[ "$BaseDifference" -eq 0 ]]; then
            echo "Executing Script- date"
    sleep 1



List Files with their absolute path using Bash

function lsfp(){
local dirpath="$1"
local recurse="$2"

if [[ "$dirpath" == "" ]]; then
echo "no path provided!"
local dirpath=$(echo "$dirpath" | sed 's:/$::g')

local DirArr=($(ls -l "$dirpath" | grep -P "^d" | grep -oP "(?<= \d\d\:\d\d ).*"))
local FileArr=($(ls -l $dirpath | grep -oP "(?<= \d\d\:\d\d ).*$"))

for file in "${FileArr[@]}"; do
local fp="$dirpath/$file"
echo "$fp"

if [[ "$recurse" != "" ]]; then
for direc in "${DirArr[@]}"; do
lsfp "$dirpath/$direc" "$recurse"

Start Powershell as Administrator in a Specific Directory

This is a continuation of a previous post on starting a process in powershell as administrator. QT Powershell #4

In this post the focus will be on lunching powershell as administrator to a specific directory.

  1. Open windows run prompt (win+R)
  2. Enter following command:
    1. powershell start-process powershell -verb runas -ArgumentList “{-NoExit -Command cd c:\tmp | clear}”
  3. In this case it will run Powershell as admin and change directory to my c:\tmp directory then clear the new shell.

Now I know that is probably is the most convenient thing way of doing this, so if you normally want to get to the same directory we can speed up the process by taking advantage of a windows shortcut.

  1. Go to your desktop or where ever you want to store your shortcut then right click > new > shortcut.
  2. In the “Type the location of the item:” field enter powershell. Then click Through the rest of the prompts.
  3. Next right click on your new shortcut and select properties.
  4. In the Target field of the “Shortcut tab” delete everything in it and paste your powershell start command (ex see previous step 2.1)
  5. Now for the most convenient part in the “Shortcut Key” field press a hotkey combination that you would like to use to execute the powershell command.
    1. ex: Ctrl+Alt+P
  6. Finally in the “Run” field use the drop down menu and select “minimized”, then apply ok.

Now you can just press your hotkey and boom you have powershell as admin in a specific directory.


Basic Powershell DNS Enumeration Module

This one will allow you too enumerate dns and filter by exclusion or inclusion of different record types.

    .SYNOPSIS simplifies dns enum and record type filtering 
    .EXAMPLE Ex1: (use default zone and server, return all records found) .\Get-DNSEnum.ps1 or 
            Ex2: (specifiy zone and server, return all except SVR and NS Records) .\Get-DNSEnum.ps1 -Zone domain.local -dc DomainControllerName -Exlcude 'SVR','NS' 
    .DESCRIPTION Detailed Syntax: .\ -[Zone|z] dnszone -[Domain|dc] dns or domaincontroller -[ExcludeList|e] 'record','type(s)','to','exclude' -[IncludeList|i] 'record','type(s)','to','include' 
    .NOTES Author: John Klann 
    [Parameter(Mandatory=$False, HelpMessage='Dns Zone aka domain' )]
    [string]$Zone = 'default zone / domain',
    [Parameter(Mandatory=$False, HelpMessage='Domain Controller')]
    [string]$Domain = 'default domain controller',
    [Parameter(Mandatory=$False, HelpMessage='Record Type Include list')]
    [Parameter(Mandatory=$False, HelpMessage='Record Type Exclude List')]

if ($ExcludeList.Count -gt 0)
    Get-DnsServerResourceRecord -ZoneName $Zone -ComputerName $Domain | Where-Object { $_.RecordType -notin $ExcludeList }
elseif ($IncludeList.Count -gt 0)
    Get-DnsServerResourceRecord -ZoneName $Zone -ComputerName $Domain | Where-Object { $_.RecordType -in $IncludeList }
    Get-DnsServerResourceRecord -ZoneName $Zone -ComputerName $Domain



How to Set Environment Path Variables

Yay another powershell tip. Super useful and you could script it out if you want to carry around your custom environment paths and install them on any windows machine.

Admin PowerShell Prompt:

  1. Command Syntax:
     $pathtext=Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" -Name "Path" | %{$_.Path}
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" -Name "Path" -Value "$pathtext" 
  2. Example adding Cygwin bin directory:
     $pathtext=Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" -Name "Path" | %{$_.Path}
    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" -Name "Path" -Value "$pathtext" 
  3. Output:
  4. windows_powershell_ps_setting_windows_environment_path
  5. Logoff and Back in for it to take effect.
    shutdown /l



How to get and set a registry key using powershell

Hi Just a quick blurb on how to get and set registry values with powershell:

  1. Command Syntax:
    Set-ItemProperty -Path "Hive:KeyPath" -Name "DWORD or what not to change" -Value "value to set it to"
  2. Example to Set the Cygwin root directory:
    Set-ItemProperty -Path "HKLM:\SOFTWARE\Cygwin\setup" -Name "rootdir" -Value "c:\dev\cyg"
  3. Example to Get the Cygwin root directory:
    Get-ItemProperty -Path "HKLM:\SOFTWARE\Cygwin\setup" -Name "rootdir" | %{$_.rootdir}
  4. Output:



How to Forward Ports and Use Port Proxies

So I came across a need to Forward a port from one windows machine to another windows machine and found a nice solution using netsh and port proxies. In this example I will use port proxies to forward a Remote Desktop Port  3389 (RDP)  from one  server to another to allow access to this  server via RDP by connecting to a local port like localhost:5000.

  1. Create the Port Proxy
    1. Open Admin Command Prompt:
      netsh interface portproxy add v4tov4 listenport=freeport listenaddress=localip connectport=rdpport(default rdp is 3389) connectaddress=remoteip 
    2. Example:
      netsh interface portproxy add v4tov4 listenport=5000 listenaddress= connectport=3389 connectaddress=
  2. Create the Firewall Rule:
    1. You will need to choose a local port that is not in use. If  you need to know how to check if a port is in use check out my Quick Tip Post on how to do that here: How to check if a port is in Use and What Process is running on it
    2. Command:
      netsh advfirewall firewall add rule name="Custom Port Rule" dir={in |out} action={allow | block} localport={number| n-n} protocol={TCP | UDP} remoteip={any | ip | range} profile={any | domain | public | private }


      netsh advfirewall firewall add rule name="Custom Port Forward 5000" dir=in action=allow localport=5000 protocol=TCP remoteip=any profile="Domain"
  3. Output:


  • Use the Port Proxy:
    1. Syntax:
       {localhost | ip or hostname you created the rule on}:{port number you chose} 
    2. Example:
       mstsc locahost:5000 /admin 
  • Delete the Port Proxy:
    1. Syntax:
      netsh interface portproxy delete v4tov4 listenport=portyouchose listenaddress=localip
      netsh interface portproxy delete v4tov4 listenport=5000 listenaddress=
  • Delete the Firewall Rule:
    1.  Syntax:
      netsh advfirewall firewall delete rule name="firewall rule name"
    2. Example:
      netsh advfirewall firewall delete rule name="Custom Port Forward 5000"
    3. Output:



How to check if a port is in Use and What Process is running on it

So really simple way to check if a port is in use and by what process.

  1. Method 1 CMD:
  2. Open Admin Command Prompt:
    netstat -ano | findstr "portnumber"


  3. Example using default rdp port:
    netstat -ano | findstr "3389"
  4. Output:


Method 2 PowerShell:

  1. Open Admin PowerShell Prompt:
    1. Command:
      &amp;nbsp;netstat -ano | findstr "portnumber" | Select-String -Pattern "\d+$" -AllMatches | % {$_.Matches } | foreach { tasklist |select-string -Pattern $_.Value } | Get-Unique
    2. Example using port 80:
      1. Note: this could probably be a lot cleaner but hey i did it in 5 minutes in 1 oneline :) !
         netstat -ano | findstr "80" | Select-String -Pattern "\d+$" -AllMatches |  % {$_.Matches } | foreach { tasklist |select-string -Pattern $_.Value } | Get-Unique
    3. Output:

Method 3 CMD with Cygwin:

  1. This will get all of the process running on a particular port.
    1. Note: you will need (Cygwin bin directory pathed in your environment See how to do this here: How to add environment Paths via command line (cmd, powershell) )
      1. Open Admin cmd Prompt:
        1. Command:
           for /f "delims=" %a in ('netstat -ano ^| grep "portnumber" ^| grep -m1 -oP "[\d]{1,6}$"') do @set pid=%a | tasklist | grep %a 
      2. Example using port 80:
         for /f "delims=" %a in ('netstat -ano ^| grep "80" ^| grep -m1 -oP "[\d]{1,6}$"') do @set pid=%a | tasklist | grep %a 
      3. Output:

How to add environment Paths via command line (cmd, powershell)

Here’s a quick one lol.

Quick Note: This will temporarily set the Environment path with in that shell. If you want a more permanent solution you will have to added through windows environment variables config then logoff and back in.

  1. In CMD or Powershell prompt Run this command:
    1. Syntax:
       PATH %PATH%;c:\path\you\want\to\add\ 
  2. Example Using Cygwin Bin directory:
     PATH %PATH%;c:\dev\cyg\bin\ 
  3. Output:



Basic Array Syntax, Iteration, Manipulation

So I recently took on a project where one of the requirements is that it has to be completed in Linux Bash and have as little outside dependencies as possible. So As Bash does not support multi-dimensional arrays, i’ll just cover array basics for now lol.

  1. Array Declaration:
  2. Adding to Array
    1. values
    2. variables
  3. Getting Array Length
  4. Iterating/Looping through Array (be mindful of your spacing)
    for (( i=0; i&lt;${ARRLEN}; i++ )); do
    	echo "${ARR[$i]}"
  5. Putting it all together:
    echo "adding value to array"
    echo "Array length is now: $ARRLEN"
    echo "adding variable to array"
    echo "Array length is now: $ARRLEN"
    echo "loop through array"
    for (( i=0; i&lt;${ARRLEN}; i++ )); do
            echo "Array Key/Index: $i holds Value: ${ARR[$i]}"
  6. Returns: