Powershell - auto-mate/CheatSheetWiki GitHub Wiki

Powershell

Bypass Policy

Run From a batch file.

REM Use -WindowStyle Minimized in this bat file and

REM $Form.Visible()=$true; 
REM In the PS1 file if using GUI forms

@echo off
Start /MIN "PS Form" powershell  -ExecutionPolicy Bypass -file "fullPathAndScriptName"

Run From CMD

powershell -ExecutionPolicy ByPass ".\<folder>\<folder>\<fileName>.ps1"

Drive Space

$z=[system.io.driveinfo]("C:\")
$z.TotalFreeSpace/(1024*1024*1024) # OR write-host  ($z.TotalFreeSpace/(1024*1024*1024))

Form - Simple

# Create New Form
$frm= New-Object system.windows.forms.form

# Create New Button
$button=New-Object system.windows.forms.button

# Set Button Features
$button.top=50
$button.left=50
$button.text="Close"
$button.name="Button_No_01"

# Add Button To Form
$frm.controls.add($button)

# Add Click Action To Button
$Button.Add_Click({[System.Windows.Forms.MessageBox]::Show("Hello World." , "Dialog Box")})

# Display Form
$frm.showdialog()

functions

function SquareIt($x) {
    return $x * $x;
}

function DoubleIt($x) {
    return $x + $x;
}


SquareIt(4)
DoubleIt(16)

# multi parameter example

function ConfirmFileExists( $fileDetails ) {
    $dlList = Get-ChildItem $fileDetails[0];
    foreach ($dl in $dlList ) {
        # NB -eq is case sensitive
        if ($dl.name -eq $fileDetails[1] ) { 
            return $true;
        }
    }
    return $false;
}

$result = ConfirmFileExists $ENV:USERPROFILE\Downloads\, "SomeFile.SomeExt";

User Input - Simple

# Read from Command Line to $n
$n = Read-Host  
# Read Password from Command Line to $pw (securly)  
$pw = Read-Host -Prompt "Enter PW" -AsSecureString
# Write to Command Line from $n  
Write-Host $n   

# secure string to plain text
$pw               = Read-Host -Prompt "Enter PW" -AsSecureString
$BSTR             = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PW)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

Yes/No

$z=[System.Windows.MessageBox]::Show("Form Body Text", "Form Title", "YesNo", "Question")
Write-Output $z

#Alternatives to YesNo
#=====================
#OK The message box displays an OK button.
#OKCancel The message box displays OK and Cancel buttons.
#YesNo The message box displays Yes and No buttons.
#YesNoCancel The message box displays Yes, No, and Cancel buttons

#Alternatives to Question
#========================
#Question
#Asterisk
#Error
#Exclamation
#Hand
#Information
#None
#Stop
#Warning

Text Input

[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')  

$title = 'Some Title'
$msg   = 'Some Info:'

$text = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)
Write-Output $text

Open A File And Read Lines

$file='C:\temp\file.txt'  
$reader = New-Object -TypeName System.IO.StreamReader -ArgumentList $file  
while ($x=$reader.readline()) {  
  echo $x   #  "OR" Write-Host $x  
}  

Open File and Read (Skip N Lines)

Function Read-File-SkipFirstrows {  

Param([string]$fileName,[int]$skipRows)      

Process  
{  
    $FileReader = New-Object System.IO.StreamReader($fileName)  
    [int]$rowNo = 1  

    while (($row = $FileReader.Readline()) -ne $null)  
    {  
        if ($rowNo -ge $skipRows)  
        {  
            Write-Host $rowNo.ToString() $row  
        }  
        $rowNo=$rowNo + 1  
    }  

    $FileReader.Dispose()  
  }  
}  

Read-File-SkipFirstrows -file "C:\temp\xxxxxxx.txt" -skip 2

Open File and Read (Skip X Lines :: Read Only First Y Lines)

Function Read-File-SkipFirst_X_Rows_ShowFirst_Y_YRows {
    
    Param([string]$fileName,[int]$skipRows,[int]$first)
    
    Process
    {
        $FileReader = New-Object System.IO.StreamReader($fileName)
        [int]$rowNo = 1

        while (($row = $FileReader.Readline()) -ne $null)
        {
            if ($rowNo -ge $skipRows)
            {
                Write-Host $rowNo.ToString() $row
            }
            $rowNo=$rowNo + 1
            if ($rowNo -gt $first) {break;}
        }

        $FileReader.Dispose()
    }
}

Read-File-SkipFirst_X_Rows_ShowFirst_Y_YRows -file "C:\temp\xxxxx.txt" -skip 10 -first 20

Open File and Read (Skip X Lines :: Read Only First Y Lines :: Ignore Lines Matching a Simple Pattern)

Function Read-File-SkipFirst_X_Rows_ShowFirst_Y_YRows {

    Param([string]$fileName,[int]$skipRows,[int]$first,[String]$StringToExclude)

    Process
    {
        $FileReader = New-Object System.IO.StreamReader($fileName)
        [int]$rowNo = 1

        while (($row = $FileReader.Readline()) -ne $null)
        {
            if ($rowNo -ge $skipRows -and  ($row | select-string -pattern  $StringToExclude -simplematch) -eq $null  )
            {
                Write-Host $rowNo.ToString() $row
            }
            $rowNo=$rowNo + 1
            if ($rowNo -gt $first) {break;}
        }
    
    }
}

Read-File-SkipFirst_X_Rows_ShowFirst_Y_YRows -file "C:\temp\xxxxxxxx.txt" -skip 10 -first 100 -StringToExclude "|------------------------------"

Close all ie browsers

<#
Close all ie browsers 
#>

$signature = @"
  [DllImport("user32.dll")] 
  public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
"@

$FindWindowAPI   = Add-Type -memberDefinition $signature -name "Win32FindWindow"      -namespace Win32Functions -passThru


Write-Host "Killing IE"

$ieProcs=Get-Process iexplore

while ($ieProcs -ne $null) {
  if((Get-Process iexplore).count -gt 1 ){
    Write-Debug "Stopping " $ieProcs[0].Id  
    Stop-Process -Id $ieProcs[0].Id}
  else {
    Write-Debug "Stopping " $ieProcs.Id  
    Stop-Process -Id $ieProcs.Id}
  $ieProcs=Get-Process iexplore
}

Write-Host "Killed IE(s)"


start-process "Powershell" -ArgumentList  "-ExecutionPolicy Bypass -file C:\.....\Close_JS_Message.ps1"

$ie = new-object -ComObject "InternetExplorer.Application"
$ie.visible = $false
$requestUrl = "http://webaddress...."
$ie.navigate2($requestUrl)

start-sleep -seconds 5

$ie | Get-Member

start-sleep -seconds 5

$ie.visible = $true

return


# while($ie.Busy) { Start-Sleep -Milliseconds 100 }  
# $doc = $ie.Document  
# $doc.getElementsByTagName("input") | % {  
#    if ($_.id -ne $null){  
#        if ($_.id.Contains($buttonIdFragment)) { $btn = $_ }  
#        if ($_.id.Contains($acceptTermsInputFragment)) { $at = $_ }  
#        if ($_.id.Contains($passwordIdFragment)) { $pwd = $_ }  
#        if ($_.id.Contains($userIdFragment)) { $user = $_ }  
#    }  
# }  
# $user.value = "<user name="" here="">"  
# $pwd.value = "<password here="">"  
# $at.checked = "checked"  
# $btn.disabled = $false  
# $btn.click()  

Parse Text

$toParse = "123,45,OK,31,70,FAIL,2"
$l=$toParse.split(",")

for ($n = 0 ;$n -lt $l.length;$n++) {
  Write-Host $l[$n]
}

Close JS Message

<#

Waits until
Dialog With Title "Message from webpage" is found and closes it!

#>


$sig1=@'
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(String sClassName, String sAppName);
'@

$sig2=@'
[DllImport("user32.dll", SetLastError=true)]
public static extern IntPtr SetForegroundWindow(IntPtr hWnd);
'@

$SS1 = Add-Type -Namespace Win32 -Name Funcs3 -MemberDefinition $sig1 -PassThru
$SS2 = Add-Type -Namespace Win32 -Name Funcs4 -MemberDefinition $sig2 -PassThru

$hwnd = $SS1::FindWindow('#32770', "Message from webpage") 

While ($SS1::FindWindow('#32770', "Message from webpage") -eq 0) {
    $hwnd = $SS1::FindWindow('#32770', "Message from webpage") 
}


Add-Type -AssemblyName System.Windows.Forms
$SS2::SetForegroundWindow($hwnd -as [long]);

[System.Windows.Forms.SendKeys]::SendWait('~');

General Reference

[System.IO.Directory].GetMember               # NON - STATIC FUNCTION  
[System.IO.Directory]::GetCurrentDirectory()  # STATIC FUNCTION  
[System.IO.FileInfo]("C:\temp\1.js")          # ??

Get Text From Objects with !!! OUT-STRING !!!!  see clipboard example  

# single line comment

<# 
   multi line 
   comment
#>

backtick ` for line continuation.

verb-noun naming convention

tab to auto complete

variables start with $

escape char `
return and new line in string `r`n

write to console with "Write-Output" or "Write-Host" "Out-Host" NB -paging (flag)
write to other "Out-Null","Out-Printer -Name 'printername' ","Out-File -Filepath C:\etc..."

Windows Management Instrumentation listing "Get-WmiObject -List"

OUT-STRING                                    # Get Text From Objects with !!! OUT-STRING !!!!  see clipboard example  
Get-ComputerInfo                              # Your Computer info
Pause                                         # Wait For User To Press
Get-FileHash -Algorithm SHA256 -Path C:\..... # calc file hash
Get-Location                                  # get current dir
Set-Location <PATH>                           # set current dir
Get-Random                                    # Random Number
Get-ScheduledTask                             # show Scheduled Tasks
Get-Service                                   # Get Services List
Get-StartApps                                 # Get StartApps List
Get-TimeZone                                  # Get TimeZone
Split-Path  -Parent -Leaf                     # Path and Filename
Invoke-WebRequest -Uri http://bbc.co.uk       # can send credentials with get-credentials
Test-Path "C:\temp"                           # File/Path Exists
| Out-GridView                                # Nice Filterable Output View
New-Guid                                      # Make a GUID
Resolve-Path C:\... -Relative                 # Get Relative Path
Import-Csv                                    # Import To Variable via $n = Import-Csv -Path C:\...\example.csv
                                              #      View Record 1 $n[0]
                                              #      View Field Name in Record 1 $n[0].Name
                                              #      Count Records $n.Length
ConvertFrom-Json                              # Convert From JSON and Show Sample Data via 
                                              #      $js = ConvertFrom-Json '{"Array1":["1","2","3"],"Array2":["4","5","6"]}'
                                              #      $js[0].Array1[0] # = 1
                                              #      $js[0].Array2[2] # = 6
                                              #      NB Count on Array Only as mix of objects and arrays e.g. $js[0].Array1.Count

Compress-Archive -Path C:\... -DestinationPath C:\....zip            # zip write/extract
Expand-Archive   -Path C:\....zip -DestinationPath C:\...\newFolder  # zip write/extract

# Convert From And To Require PS Object
#######################################

# From array of strings @("Hello;World","You;Again") 
$psOb = @("Hello;World","You;Again") | ConvertFrom-String  -Delimiter ";" -PropertyNames "F1","F2" 

# Access with 
$psOb.F2
$psOb.F2[0] #etc

# Convert to csv text format
$psOb | ConvertTo-Csv -Delimiter "," 

# Convert To HTML/JSON 
$psOb | ConvertTo-Html 
$psOb | ConvertTo-Json



-? after command shows help

> writes to file
| pipes NB ()| completes the command in () before piping.  Can be useful where files are still open etc! 

Operators
=========
 -eq             Equal
 -ne             Not equal
 -ge             Greater than or equal
 -gt             Greater than
 -lt             Less than
 -le             Less than or equal
 -like           Wildcard comparison
 -notlike        Wildcard comparison
 -match          Regular expression comparison
 -notmatch       Regular expression comparison
 -replace        Replace operator
 -contains       Containment operator
 -notcontains    Containment operator
 -shl            Shift bits left (PowerShell 3.0)
 -shr            Shift bits right – preserves sign for signed values.(PowerShell 3.0)
 -in             Like –contains, but with the operands reversed.(PowerShell 3.0)
 -notin          Like –notcontains, but with the operands reversed.(PowerShell 3.0)



Version Info=$PSVersionTable.psversion


Static Class Access
===================
[System.Environment]::  (tab/tab)
[System.Math]::   (tab/tab)
[System.Math]|Get-Member -Static -MemberType Methods (more math info than just Get_Member)
[System.Math]::Round(120.44444,2)=120.44 etc...

arrays (hashtable)
==================
# create array # (hashtable)
    $arr=@{}
    $arr["ARR"] = @{}
    $arr["ARR"]["ITEM"] = @{}
# add value item
    $arr["ARR"]["ITEM"]["SIZE"] ="M"
# retrieve value
    $arr.arr.item.size

  $update_def = @{
    sourceRptPath    = "..\Temp\TMP.txt";
    outputSqlPath    = "..\Temp\TMP.sql";
    database         = "MyDb";
    schema           = "dbo";
    table            = "MyTable";
    sampleHeader     = "Header";
    datFieldNosCsv   = "4";
    numFieldNosCsv   = "";
    totalFields      = "52";
    fieldLocationCsv = "22,23,7,25,5,4,6,50,36,8";
    timestamp        = "[TimeStamp]";
    fields           = "[F1],  " + 
                       "[F2], " + 
                       "[F3]";
    sqlbcpFlag       = "sql";
  }

Bypass the execution policy for a particular file 
=================================================
ExecutionPolicy bypass -file myFile.ps

#E.G.loading a Module bypassing security using module function and resetting security
Set-ExecutionPolicy -Force -Scope CurrentUser unrestricted 
Import-Module C:\Temp\functions.psm1 
$x = function_from_module
Set-ExecutionPolicy -Force -Scope CurrentUser AllSigned

In batch file example
=====================
@echo off
Start /MIN "PS Form" powershell -WindowStyle Minimized -ExecutionPolicy Bypass -file "C:\Users\andrew.harper\Desktop\Local Work\Powershell\DetailedForm.ps1"

OTHER
=====
Get-Childitem e.g. Get-Childitem C:\Windows\*.log

Get-Command = Full List of commands
Get-Command some-command | Get-Member


"Format" Pipe info to Format then Format-Wide, Format-List, and Format-Table  (specific items can be selected see MS pages https://msdn.microsoft.com/powershell/scripting/topic/getting-started-with-windows-powershell)

using com objects
=================
New-Object -ComObject WScript.Shell
New-Object -ComObject WScript.Network
New-Object -ComObject Scripting.Dictionary
New-Object -ComObject Scripting.FileSystemObject

using ie
========
$ie = New-Object -ComObject InternetExplorer.Application
$ie | Get-Member to show all methods/properties
$ie.visible = $true (use a member from the list NB true=$true)
$ie.quit()

ForEach-Object Example
======================
Sx=Get-WmiObject -Class Win32_LogicalDisk | ForEach-Object -Process {($_.FreeSpace)/1024.0/1024.0}
$x[1]=value of object 1

Com Items List

Gets a list of com item names registered on the PC likes of WScript.Shell
Uses Aliases Get-Childitem (gci), Where-Object (?),Get-ItemProperty (gp), Format-Table (ft)

gci HKLM:\Software\Classes -ea 0| ? {$_.PSChildName -match '^\w+\.\w+$' -and 
(gp "$($_.PSPath)\CLSID" -ea 0)} | ft PSChildName

Date

$VarName=Get-Date
$Yesterday=Get-Date.AddDays(-1)
# Formated Date $FmtDate = get-date -Format "yyyyMMdd_HHmmss"  

Dir

Get-ChildItem -File -Filter *PartOfFileNameToLookFor* -Path "C:\Some\Path\" -Recurse

If

NB -LT,-LE,-GT,-GE,-EQ

IF ($x -LT $y) {Write-Output $date.Year}

For

NB -LT,-LE,-GT,-GE,-EQ Exit with {Break}

for ( $n=0; $n -LT 10; $n++ ) {  
  Write-Output $n
}  

Ping Port

Test-NetConnection <IP> -port <PORT>  

Kill by Window Title

Get-Process | Where-Object {$_.MainWindowTitle.Contains("<PART_OF_WINDOW_TITLE>")} | stop-Process 

ForEach-Object

ForEach-Object -Process {some ps script with $_ as pipped in item }

Get-ChildItem -Path  C:\inetpub\wwwroot\Jobs\* -Recurse  -Include *.bat,*.sql,*.vbs,*.cs,*.cpp,*.ps1,*.py,*.php,*.js,*.wsf  | ForEach-Object -Process { Get-Content $_.FullName } | Measure-Object -Line  

NB you can use -Begin {<some_scriptblock>} and -End {<some_scriptblock>} to run seperate scipt at begining and end.

Parse Program For SAP Reports

Settings text file (its path used for input to parser)

# add 1 sourceRptPath full path to report File parsed with "|"  
# add 1 outputSqlPath full path to output .sql file
# add 1 Database name without []
# add 1 Schema name without []
# add 1 Table name without []
# add 1 sampleHeader to skip
# add 1 datFieldNosCsv csv list of field numbers for dates
# add 1 numFieldNosCsv csv list of numeric field numbers for -ve conv
# add fields as required split with ,

sourceRptPath;<\\path..\REPORTFILE from SAP>
outputSqlPath;<\\path..\REPORTFILE_as_sql.sql>
database;<DBNAME>
schema;<DBO>
table;<TABLE NAME>
sampleHeader;<HEADER SAMPLE FIRST COL TITLE>
datFieldNosCsv;<csv list of cols with dates>
numFieldNosCsv;<csv list of cols with numbers>
fields;[field1],[field2],
fields;[field3],...,[field4]

Powershell SAP Parser Program (setup file path as parameter)

function NumConv( $numText ) {

    $ntSplt = $numText.trim().split("-");


    if ($ntSplt.Count -eq 2 ) {
        return  "-"+$ntSplt[0]
    } 
    else 
    {
        return $numText
    }
}


$formatFile=$args[0];
$fields = "";
$batchSize=50;
$batchSizeCounter=1;

Get-Content $args[0] |
    ForEach-Object {

    $inStr = $_.ToString();

    if ($inStr.Length -gt 0 -And $inStr.Substring(1,1) -ne "#") {
    
        $params = $_.ToString().split(";");
        if ($params.Length -eq 2) {
            if ($params[0] -eq "sourceRptPath"  ) { $sourceRptPath  = $params[1]}
            if ($params[0] -eq "outputSqlPath"  ) { $outputSqlPath  = $params[1]}
            if ($params[0] -eq "database"       ) { $database       = $params[1]}
            if ($params[0] -eq "schema"         ) { $schema         = $params[1]}
            if ($params[0] -eq "table"          ) { $table          = $params[1]}
            if ($params[0] -eq "sampleHeader"   ) { $sampleHeader   = $params[1]}
            if ($params[0] -eq "datFieldNosCsv" ) { $datFieldNosCsv = $params[1]}
            if ($params[0] -eq "numFieldNosCsv" ) { $numFieldNosCsv = $params[1]}

            if ($params[0] -eq "fields" ) { $fields = $fields + $params[1] }
        
        }
    }
}

$datArray = $datFieldNosCsv.ToString().split(",")
$numArray = $numFieldNosCsv.ToString().split(",")

Set-Content -Path $outputSqlPath -Value ""

Get-Content $sourceRptPath |
    ForEach-Object {

    $x = $_.ToString().Split("|");

    if ($x.Count - 2 -eq $fields.Split(",").Count) {        

        for ($i = 0; $i -lt $datArray.Count; $i++ ) {
            $x[$datArray[$i]] = $x[$datArray[$i]].Replace(".","/")
        }

        for ( $i=0; $i -lt $numArray.Count; $i++ ) {
            $x[$numArray[$i]] = NumConv $x[$numArray[$i]]
        }

        $values = "";
        $delim=""
        for ( $i=1; $i -lt $x.Count-1; $i++ ) {
            if ($i -gt 1 ) {$delim=","}
            $values = $values + $delim +"'" + $x[$i].Trim() + "'";
        }



        $out="INSERT INTO ["+$database+"].["+$schema+"].["+$table+"] ("+$fields+") VALUES ("+$values+")"
    
        if ($x[1].trim() -ne $sampleHeader.trim()) {
            Add-Content -Path $outputSqlPath -Value $out

            $batchSizeCounter += 1;
            if ($batchSizeCounter -gt $batchSize ) {
                $batchSizeCounter = 1;
                Add-Content -Path $outputSqlPath -Value "GO";
            }
        }
    
    }
}

Arrays

See also General Reference

Arrays use += to add item even though fixed! [e.g. $ar=@();$ar += 200;$ar += 100]

Arrays are fixed size use $x = @(0) * $fldCount to create an array called $x of size $fldcount filled with 0's use $x[$n] to retrieve a value from index $n use $x[$n] = $v to set a value of $v in index $n

# FIND ARRAY DUPLICATES  
#######################
$x = @(1,2,3,4,5,6,1,2,4)

$a = $x|sort
$b = $x|sort -Unique

$diff = Compare-Object -ReferenceObject $a -DifferenceObject $b
$diff | ForEach-Object {echo $_.InputObject}


<#

function creates an array  of size $fldCount
         containing arrays of size $observations

In this example 3 fields 5 observations

The array containing 0's is passedback to $y

an array $list of size $fldCount is created to hold the mode value (most common observation)  

15 observations are fed in 

each field then uses group-object and select -first 1 to get the mode and add it to the $list array

#>

function delPos( $fldCount,$observations ) {


    $x = @(0) * $fldCount


    for ( $i = 0; $i -lt $fldCount; $i++ ) {
        $x[$i] = @(0) * $observations
    }

    return $x

}

$flds = 3

$y = delPos $flds 5
$list=@(0) * $flds

$y[0][0] = 3
$y[0][1] = 3
$y[0][2] = 3
$y[0][3] = 4
$y[0][4] = 2
$y[1][0] = 8
$y[1][1] = 8
$y[1][2] = 3
$y[1][3] = 4
$y[1][4] = 8
$y[2][0] = 4
$y[2][1] = 4
$y[2][2] = 3
$y[2][3] = 4
$y[2][4] = 2

for ($i = 0; $i -lt $flds; $i++) {
    $list[$i] = $y[$i]| Group-Object| SELECT -First 1 -Property Name 
}

$list

Import

<# Example Import a module C:\Temp\functions.psm1  containing a function square #>
Set-ExecutionPolicy -Force -Scope CurrentUser unrestricted 
Import-Module C:\Temp\functions.psm1 
square 4
Set-ExecutionPolicy -Force -Scope CurrentUser AllSigned

Args

Input params to powershell file

    $someVar=$args[0];

Snippets ISE Only

ctrl+J

require unrestricted policy

kept in $home\Documents\WindowsPowerShell\Snippets edit and delete as required

Add

NB escape backtics on $

$sn = 
"
For (`$i = 0; `$i -lt 10; `$i++ ) {
    echo `$i;
}
"


New-ISESnippet -Text $sn -Title ForLoop -Description "Adds a ForLoop." -Author "Automate" -Force  

Remove

# Remove (stays till ISE re-opened)
Get-IseSnippet | Where-Object -Property  Name -like "ForLoop*" | Remove-Item

Here Strings C Sharp Example

For holding program text

$n   = 6
$adj = 1

Add-Type -Language CSharp -TypeDefinition @"

    public class CS_EasyMath {
    
        public static int Square(int x) {
            return (x+$adj)*(x+$adj);
        }
    }

"@
[CS_EasyMath]::Square($n)

Orphaned Processes

# Find Orphaned Processes  
# From Admin CMD  
# Run as System PSExec -sid "powerhshell"  
$procsWithParent = Get-WmiObject -Class "win32_process" | Select-Object ProcessId,ParentProcessId,commandline,ProcessName  
$orphaned = $procsWithParent | Where-Object -Property ParentProcessId -NotIn $procsWithParent.ProcessId   
$orphaned  

Outlook Not Spam Confirmation

Run constantly it works!

Write-Output "START..."

$WM_LBUTTONDOWN =  0x0201
$WM_LBUTTONUP   =  0x0202
$BM_CLICK       =  0x00f5

Write-Output "Adding DLL Here Strings"

$wThread = @'
[DllImport("user32.dll")]
public static extern bool AttachThreadInput(IntPtr idAttach, IntPtr idAttachTo, bool fAttach);
'@

$wFw=@'
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(String sClassName, String sAppName);
'@

$wFwEx=@'
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(long hWnd,long lngNull,String classString,String textString);
'@

$wStFc=@'
[DllImport("user32.dll")]
public static extern IntPtr SetFocus(long hWnd);
'@

$wStAw=@'
[DllImport("user32.dll")]
public static extern IntPtr SetActiveWindow(long hWnd);
'@

$wSndMsg=@'
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(long hWnd,long wMsg, long wParam, long Iparam);
'@

Write-Output "Adding Types"

$fFw     = Add-Type -Namespace Win32 -Name fFw     -MemberDefinition $wFw     -PassThru
$fFwEx   = Add-Type -Namespace Win32 -Name fFwEx   -MemberDefinition $wFwEx   -PassThru
$fStAw   = Add-Type -Namespace Win32 -Name fSetAw  -MemberDefinition $wStAw   -PassThru
$fStFc   = Add-Type -Namespace Win32 -Name fSetFc  -MemberDefinition $wStFc   -PassThru
$fSndMsg = Add-Type -Namespace Win32 -Name fSndMsg -MemberDefinition $wSndMsg -PassThru

Write-Output "Start Loop"

while ( 1 -eq 1 ) {

  Write-Output "Sleep 5"
  start-sleep 5

  $hwndMsgBox = $fFw::FindWindow('#32770', "Microsoft Outlook") 
  if ($hwndMsgBox -ne  0) {
        Write-Output "Sleep 7"
        start-sleep 7

        $hButton = $fFwEx::FindWindowEx($hwndMsgBox,0,"button","Allow")     
        $setAWinRet = $fStAw::SetActiveWindow($hwndMsgBox)
        #$setFocusRet = $fStFc::SetFocus($hButton)

        $msgMDRet = $fSndMsg::SendMessage($hButton, $BM_CLICK, 0x0, 0x0);        
    
    
        start-sleep 1

  } 

}



<#

     DWORD currentThreadId = GetCurrentThreadId();
     DWORD otherThreadId = GetWindowThreadProcessId(targetHwnd, NULL);
     if( otherThreadId == 0 ) return 1;
     if( otherThreadId != currentThreadId )
     {
       AttachThreadInput(currentThreadId, otherThreadId, TRUE);
     }

     SetActiveWindow(targetHwnd);

     if( otherThreadId != currentThreadId )
     {
       AttachThreadInput(currentThreadId, otherThreadId, FALSE);
     }


#>

Cmd Dos use in PS sheduled tasks backup

$someVar = Dos Command will return the output from that command into $someVar.

# READ DOS OUTPUT TO PS VAR
###########################
$tskStrs = schtasks /query /FO LIST| Findstr TaskName:

# CHANGE FOLDER TO REQUIRED OUTPUT FOLDER
#########################################
$folder = "C:\temp\Jobs\"

foreach($tStr in $tskStrs) {

    #Get TaskPath

    $tsLen = $tStr.Length;
    $tPath = $tStr.Substring(9,$tsLen - 9).trim();


    #Get TaskName

    $pathArray = $tPath.Split("\");
    $tName = $pathArray[ $pathArray.Length-1 ];


    # CHANGE \Cl \MI ETC TO SELECT ONLY REQUIRED JOBS
    #################################################
    if ( $tPath.StartsWith("\Cl") -or 
         $tPath.StartsWith("\Mi") ) {
    
        schtasks /query /XML /TN $tPath > $folder$tName".xml"
    

    }


}

Top

Basics

$path = <SOME FILE PATH>;  
Get-Content $path -First 20;  

An example search files in a given location for date $from which contain "????" in the first 20 lines

$search = "????";
$From = '2021-05-01' # 00:00
$To   = '2021-05-02' # Before this

echo $search;

$downloads = Get-ChildItem 'C:\....'  -Name ;

foreach ( $file in $downloads ) {

    $path     = 'C:\.....\'+$file;
    $pathInfo =  Get-Item  $path;

    if ($pathInfo.LastWriteTime -GT $From -AND $pathInfo.LastWriteTime -LT $To) {

    $content  =  Get-Content $path -First 20;

    $found = Select-String -InputObject $content -Pattern $search  ;

    foreach ( $item in $found ) {
        echo $pathInfo.LastWriteTime $path ;
    }

    }

}

HEAD

Get-Content -first 10

SQL

$sqlConn = New-Object System.Data.SqlClient.SqlConnection; $sqlConn.ConnectionString = "Server=;Integrated Security = true;Initial Catalog="; $sqlConn.Open();

$sqlcmd = New-Object System.Data.SqlClient.SqlCommand; $sqlcmd.Connection = $sqlConn; $query = "SELECT * FROM "; $sqlcmd.CommandText = $query;

$adp = New-Object System.Data.SqlClient.SqlDataAdapter $sqlcmd; $data = New-Object System.Data.DataSet;

$adp.Fill($data) ; $sqlConn.Close();

for ( $n = 0; $n -lt $data.Tables[0].Rows.Count; $n++ ) { $outRow = ""; for ( $p = 0; $p -lt $data.Tables[0].Columns.Count; $p++ ) { $outRow += " >>> " + $data.Tables[0].Rows[$n][$p]; } $outRow = $outRow.Replace("\n",""); $outRow; }

easy sql

# Read Data to $data
$data = Invoke-Sqlcmd -ServerInstance "<SOME_SERVER>" -Database "<SOME_DATABASE>" -Query "SELECT TOP 10 * FROM <SOME_TABLE>"

# get a field count if needed
foreach ($prop in  Get-Member -InputObject $data[0] -MemberType Property ) {$ctr ++}

# loop records
foreach ($rec in $data) { 
    # loop fields
    for ($i=0; $i -lt $ctr; $i++) {    
        $rec[$i];
    }
}

Delete Files By Date

e.g. files in path where date is less than 2021-06-15

get-item C:\path\*    | Where-Object {$_.LastWriteTime -lt '2021-06-15' } | Where-Object {del $_.FullName}

to show files first

get-item C:\path\*    | Where-Object {$_.LastWriteTime -lt '2021-06-15' } | Where-Object {$_.FullName}

alt use of Where-Object (list contents of files in path)
get-item C:\path* | Where-Object LastWriteTime -lt '2021-06-16' | get-content

Email

$body = 
 "<html>
  <body>
    <img src=""cid:<fileNameOnlyNoPath>.png""></img>
    <br><br>
    <b><u>MY_TITLE</u></b>
    <br><br>
    Dear [Name],
    <br><br>
    Welcome to ""WHATEVER IT IS"" Here is some link.
    <br><br>
    <a href=""http://......html"">TextForLink</a>
    <br><br>
    MoreText
    <br><br>
    MoreText.
    <br><br>
    Best Regards,
    <br><br>
    TheSender
  </body>
</html>" 

Send-MailMessage -Subject "SOME_SUBJECT" -BodyAsHtml $body -From "SENDER@EMAIL" -to "RECIEVER@EMAIL" -SmtpServer "SOME_SMTP_SERVER" -Attachments "C:\...fullPathTo....<fileNameOnlyNoPath>.png"  

#or 
Send-MailMessage -Subject "SOME_SUBJECT" -BodyAsHtml $body -From "SENDER@EMAIL" -to @("RECIEVER_01@EMAIL","RECIEVER_02@EMAIL") -SmtpServer "SOME_SMTP_SERVER" -Attachments "C:\...fullPathTo....<fileNameOnlyNoPath>.png"  

Excel

$ExcelFile = "C:\.....xlsx";  
$objExcel = New-Object -ComObject Excel.Application;  
$WorkBook = $objExcel.Workbooks.Open($ExcelFile);  
$WorkSheet = $WorkBook.Sheets.Item(1);  
$x = $WorkSheet.Range("A1").value2;  
echo $x;  
$WorkBook.close();   
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($objExcel);  
Kill -Name Excel;  

Open A File And Write

# optional -Append  
echo $someString | Out-File -Encoding <OPTIONS> -FilePath <PATH>   

dotnet

To use .net methods enter as below

Enter as [Namespace.Class]::Method

File Is Locked check

function waitTillFileUnLocked($fileName) {  
    $loopEnd="f"  
    while ($loopEnd -eq "f") {   
      Wait-Event -Timeout 1  
      try{  
        [System.IO.File]::OpenWrite($fileName).close();  
        $loopEnd="t"  
      } catch {}  
    }  
  }  

Set Working Directory

Set-Location -path $PSScriptRoot

Dot Sourcing

To load a function in external file in the current file

. .\<filename.ps1>
. .\<SomeFolder>\<SomeFile.ps1>

SAP Automation

# F U N C T I O N S  F O R  U S E  I N  S C R I P T

 #-Get-Property--------------------------------------------------------
    function Get-Property {
      param([__ComObject] $object, [String] $propertyName)
      $objectType = [System.Type]::GetType($object)
      $objectType.InvokeMember($propertyName,
        "GetProperty", $NULL, $object, $NULL)
    }

  #-Invoke-Method-------------------------------------------------------
    function Invoke-Method {
      param([__ComObject] $object, [String] $methodName,
        $methodParameters)
      $objectType = [System.Type]::GetType($object)
      $output = $objectType.InvokeMember($methodName,
        "InvokeMethod", $NULL, $object, $methodParameters)
      if ( $output ) { $output }
    }


#-Wait Till File Unlocked------------------------------------------------
function waitTillFileUnLocked($fileName) {
    $loopEnd="f"
    while ($loopEnd -eq "f") { 
      Wait-Event -Timeout 1
      try{
        [System.IO.File]::OpenWrite($fileName).close();
        $loopEnd="t"
      } catch {}
    }
  }

# S T A R T S  H E R E
Set-Location -path $PSScriptRoot
Clear-Host;

# KILL ANY OPEN SAP AND REOPEN WAIT 15SEC and CONTINUE
Stop-Process -Name saplogon -ErrorAction SilentlyContinue
start-Process -FilePath "C:\Program Files (x86)\SAP\FrontEnd\SAPgui\saplogon.exe" 
Wait-Event -Timeout 15

# S A P  I N I T I A L I S A T I O N

# Needed for [microsoft.visualbasic.Interaction] to exist
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")

# C o n n e c t  t o  S A P

# if connection exists USE >> $connection  = Get-Property  $application "Children" @(0) 
$SapGuiAuto  = [microsoft.visualbasic.Interaction]::GetObject("SAPGUI")
$application = Invoke-Method $SapGuiAuto  "GetScriptingEngine"
# $connection  = $application.OpenConnection("<NAME-OF-CONNECTION-ON-MENU>") 
$connection  = $application.OpenConnectionByConnectionString("/R/<NAME>/G/<GROUP>", "true", "true")
$session     = Get-Property  $connection  "Children" @(0)
$session.findById("wnd[0]").maximize()

# L o g  i n t o  S A P

# Login
$session.FindById( "/app/con[0]/ses[0]/wnd[0]/usr/txtRSYST-BNAME" ).text = <UID>
$session.FindById( "/app/con[0]/ses[0]/wnd[0]/usr/pwdRSYST-BCODE" ).text = <PASSWORD>
$session.FindById( "/app/con[0]/ses[0]/wnd[0]/tbar[0]/btn[0]"     ).press()
# multilogon choose to run this script over any already running
try {
    if ( $session.FindById( "/app/con[0]/ses[0]/wnd[1]" ).text() -eq "License Information for Multiple Logons") {
        $session.FindById( "/app/con[0]/ses[0]/wnd[1]/usr/radMULTI_LOGON_OPT1" ).select()  #  radMULTI_LOGON_OPT3 to Terminate
        $session.FindById( "/app/con[0]/ses[0]/wnd[1]/tbar[0]/btn[0]"          ).press()
    }
}
catch {
Write-Output "No Earlier Logon"
}

$PS variables

Various data is available in $PS variables e.g. $PSVersionTable , $PSCulture, $PSEdition, $PSHOME, $psISE, $PSSessionApplicationName, $PSSessionConfigurationName, $PSSessionOption, $PSUICulture, $psUnsupportedConsoleApplications

pipes

Using Get-Member

NB here we are using data from Get-Alias, it could be any Get function or even a variable say $sql from some SQL returned via
$sql = Invoke-Sqlcmd -ServerInstance <SERVER_NAME> -Query "SELECT TOP 10 * FROM

"

e.g.

Look at getting info from Get-Alias After running Get-Alias we will see a list of Alias Items

Get-Alias;

After piping to Get-Member We see items we can choose on or show";

Get-Alias | Get-Member;

After piping to Select-Object and choosing a property from Get-Member we see values of the chosen property";

Get-Alias | Select-Object -Property DisplayName;

After piping to Where-Object and choosing a property from Get-Member we can filter on the chosen property";

Get-Alias | Where-Object -Property DisplayName -Like "*invoke*";

After piping this to Select-Object we can choosing which property(s) from Get-Member to view";

Get-Alias | Where-Object -Property DisplayName -Like "*invoke*" | Select-Object -Property Name,Definition

# if using $_. wrap in {}

Get-Alias | Where-Object -Property DisplayName -Like "*invoke*" | Select-Object {$_.Name,$_.Definition}

Save as

SaveVar = Get-Alias | Where-Object -Property DisplayName -Like "*invoke*" | Select-Object -Property Name,Definition

# NB using $_. gives a different result type!

Env Variables

Plenty of Environment Variables e.g. $env:USERNAME

VB dotnet

Example;

Add-Type -TypeDefinition @"

Imports System
Imports Microsoft.VisualBasic

Namespace NS1
  Public Class CL1
    Public sub main()
       MsgBox (`"Name`", MsgBoxStyle.OkOnly, `"Hello`")
    End Sub
  End Class
End Namespace
`
"@ `
-Language VisualBasic;

$instance = [NS1.CL1]::new();

$instance.main();

Clipboard

e.g. Get SQL Data and write to clipboard

$sqlData =  Invoke-Sqlcmd -ServerInstance <SERVER_NAME> -Database <DB_NAME> -Query  "SELECT TOP 10 <FIELD_NAME> from [<TABLE_NAME>]"  
$sqlData   | Format-Table -HideTableHeaders  |  Out-String | Set-Clipboard  

Active Directory and LDAP

Example for users with the same substring in their account (eg _Admin) find those users with <SOME_PROPERTY_NAME_STRING>' equal to "<SOME_SEARCH_STRING>

cls  

# GET A GROUP OF USERS WITH SIMILAR PROPERTY IN THEIR NAME
$filter ="(sAMAccountName=*<SOME_NETWORK_ACCOUNT_SUBSTRING>*)";  

# GET CREDENTIALS TO ACCESS AD  
$cred = Get-Credential `
    -UserName $env:ADDOMAIN\$env:USERNAME `
    -Message "Enter Network Login Details"     

# SET UP AD CONNECTION
$root = new-object DirectoryServices.DirectoryEntry  (
    "LDAP://" + $env:ADDOMAIN + ".com",
    $cred.UserName,
    $cred.GetNetworkCredential().Password # extracts password from secure.string
);

# SET SEARCH TO RUN IN $root and ADD FILTER/QUERY AND SET TO FIND ALL
$rootSearch           = New-Object System.DirectoryServices.DirectorySearcher($root);
$rootSearch.Filter    = $filter;
$rootSearch.PageSize  = 1000; # Allows > 1000 records search...
$resultSet            = $rootSearch.FindAll();


$Users = 0  

# COUNT $Users FOR MEMBERS OF THE FILTER/QUERY  
for ($i=0;$i -lt $resultSet.Count;$i++) {  
    if ( $resultSet[$i].Properties['<SOME_PROPERTY_NAME_STRING>'] -eq "<SOME_SEARCH_STRING>" ) {  
    $Users += 1  
    }  
}  

# SHOW RESULT  
Write-Host ("Total Users for " + $rootSearch.Filter + " = " + $Users)  

# CLEAN UP  
$resultSet.Dispose()
$rootSearch.Dispose()
$root.Close() 
$root.Dispose()

$resultSet  = $null
$rootSearch = $null
$root       = $null
$cred       = $null

Start-Process

Use -pasthru to return an object that has info about the process created!

Cast Convert

use -as to convert type e.g.

$n =  "1" -as [long];
$n.GetType();  

Scriptblock

Create a scriptblock as follows

$headerScriptText = "echo `"My Echo Text`""  
$headerScript     = [scriptblock]::Create( $headerScriptText )  

use as

$headerScript.Invoke()

# or say  

dir C:\temp | sort | ForEach-Object -Begin $headerScript  -Process {<SOME-$_SCRIPT>} -End {<SOME_ENDING_SCRIPT>}   

File System Watcher

Run a script when a file is created or deleted.

$watcher                     = [System.IO.FileSystemWatcher]::new();  
$watcher.Path                = "C:\temp";  
$watcher.EnableRaisingEvents = $true;  


Register-ObjectEvent -InputObject $watcher -Action {WRITE-HOST "New File Added";                         } -EventName Created -SourceIdentifier c_TEMP_ADDED  
Register-ObjectEvent -InputObject $watcher -Action {[System.Windows.Forms.MessageBox]::Show("DELETED");  } -EventName Deleted -SourceIdentifier c_TEMP_DELETED  

CLS  


<#  
# run when finished  
Unregister-Event -SourceIdentifier c_TEMP_ADDED  
Unregister-Event -SourceIdentifier c_TEMP_DELETED  
#>  

Or With EventInfo

e.g. Using $Event.SourceEventArgs.FullPath to get the path of a changed file and immediately back up
NB may be able to see available $Event.SourceEventArgs by loading to a global variable - TBC

$watcher                     = [System.IO.FileSystemWatcher]::new();  
$watcher.Path                = "<Path on this PC>";    
$watcher.EnableRaisingEvents = $true;      

Register-ObjectEvent `  
    -InputObject $watcher `  
    -Action {  
        $backupPath = "<path to copy to>"          
        $path       = $Event.SourceEventArgs.FullPath  
        copy-item -Path $path -Destination $backupPath  
        Write-Host "File '$path' Copied to '$backupPath'"   } `  
    -EventName Changed `  
    -SourceIdentifier BACKUP  
  
<#    
# TO REMOVE  
Unregister-Event -SourceIdentifier BACKUP  
#>        

SQL With Secure String

# BSTR basic or binary string (used in com objectes)  
$pw               = Read-Host -Prompt "Enter PW" -AsSecureString  
$BSTR             = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PW)  
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)  
Invoke-Sqlcmd -Query "SELECT 10" -ServerInstance <SERVER_ADDRESS> -Username WebUser -Password $UnsecurePassword   

Secure String

USE TO SET PASS AS ENC STRING IN FILE

Use 16 bytes as a key.

SecureStr = Read-Host -AsSecureString  
$EncStr    = ConvertFrom-SecureString -SecureString $SecureStr -Key @(16,55,43,88,125,17,247,89,192,102,101,12,213,114,88,255)  
$EncStr    | Set-Content EncStr.txt  

USE TO GET PASS FROM ENC STRING IN FILE

Use Same 16 bytes as a key.

$User      = "<SOME_USER>"  
$SecureStr = Get-Content EncStr.txt | ConvertTo-SecureString -Key @(16,55,43,88,125,17,247,89,192,102,101,12,213,114,88,255)  

$sqlCred = New-Object `
     -TypeName System.Management.Automation.PSCredential `
    -ArgumentList $User, $SecureStr 

invoke-sqlcmd `
    -ServerInstance <SERVER_NAME> `
    -Database <DB_NAME> `
    -Credential $sqlCred  `
    -TrustServerCertificate `
    -Query "SELECT 10" 

RECOVER PW

cls  
# Make Password Secure-String  
$pwSsIn            = ConvertTo-SecureString -AsPlainText "pass123" -Force   
# Encrypt Secure-String  
$pwEnc            = ConvertFrom-SecureString -SecureString $pwSsIn  
# Echo Encrypted String (Save for use in file ?)  
echo ("pwEnc  = " + $pwEnc )  

# Go From Encrypted to Secure  
$pwSsOut =  ConvertTo-SecureString $pwEnc    


# Get Data From Secured string  
$BSTR             = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwSsOut)    
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)    

#OR  

[System.Runtime.InteropServices.Marshal]::  
    PtrToStringAuto(  
        [System.Runtime.InteropServices.Marshal]::  
            SecureStringToBSTR($pwSsOut))    

Exit

Exits a script  

iis Logs

Adjust for fields not as below

Fields: date time s-computername s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken

CREATE TABLE [dbo].[<TABLE_NAME>](
	[date] [date] NULL,
	[time] [time](7) NULL,
	[server] [varchar](30) NULL,
	[ip] [varchar](20) NULL,
	[method] [varchar](20) NULL,
	[address] [varchar](255) NULL,
	[f7] [varchar](max) NULL,
	[port] [int] NULL,
	[f8] [varchar](max) NULL,
	[ip2] [varchar](100) NULL,
	[detail] [varchar](max) NULL,
	[f9] [varchar](max) NULL,
	[f10] [varchar](max) NULL,
	[res] [int] NULL,
	[f11] [int] NULL,
	[f12] [int] NULL
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO







Clear-Host

$ErrorActionPreference = "Stop"

function clean($fieldVal) {
    $rtv = $fieldVal.Replace("'",  "''"   );
    $rtv = $rtv.     Replace("`"", "```"" );
    $rtv = $rtv.     Replace("$",  "$$"   );
    return $rtv;
}







function loadFile($file) {

#Full File
$fc = Get-Content $file

#File As array of rows
$fcArr = $fc.split("`n")

for ( $i=0; $i -lt $fcArr.length; $i++) {

    #ignore comment rows
    if ($fcArr[$i].Substring(0,1) -ne "#" ) {

    #Line As array of values
    $fcLineArr=$fcArr[$i].split(" ")

    if ($fcLineArr.Length -ne 16) {
        Write-Output $fcArr[$i]
    } else {

        $sql = ("INSERT INTO <TABLE> ([date],[time],[server],[ip],[method],[address],[f7],[port],[f8],[ip2],[detail],[f9],[f10],[res],[f11],[f12])     VALUES (   `
            '"+(clean($fcLineArr[0]) )+"',  `
            '"+(clean($fcLineArr[1]) )+"',  `
            '"+(clean($fcLineArr[2]) )+"',  `
            '"+(clean($fcLineArr[3]) )+"',  `
            '"+(clean($fcLineArr[4]) )+"',  `
            '"+(clean($fcLineArr[5]) )+"',  `
            '"+(clean($fcLineArr[6]) )+"',  `
            '"+(clean($fcLineArr[7]) )+"',  `
            '"+(clean($fcLineArr[8]) )+"',  `
            '"+(clean($fcLineArr[9]) )+"',  `
            '"+(clean($fcLineArr[10]))+"',  `
            '"+(clean($fcLineArr[11]))+"',  `
            '"+(clean($fcLineArr[12]))+"',  `
            '"+(clean($fcLineArr[13]))+"',  `
            '"+(clean($fcLineArr[14]))+"',  `
            '"+(clean($fcLineArr[15]))+"')")   

        try {
        
                Invoke-Sqlcmd -ServerInstance <SERVER_NAME> -Database <DB_NAME> -Query $sql

            } catch {

                Write-Output ("ERROR ON >> " + $sql)
                return $false;

            }

    }

    }

}

return $true;

}




function main() {

    Invoke-Sqlcmd -ServerInstance <SERVER_NAME> -Database <DB_NAME> -Query "DELETE FROM <TABLE_NAME>";

    $dirs = Get-ChildItem "<PATH_TO \inetpub\logs\LogFiles>";


    for ($dir = 0; $dir -lt $dirs.Length; $dir++) {

        if ( $dirs[$dir].Name.Substring(0,3) -ne "FTP" ) {
            echo ("in " + $dirs[$dir].FullName)


            $files = Get-ChildItem $dirs[$dir].FullName

            for ($file = 0; $file -lt $files.Length; $file++) {

                # DATE RESTRICT                    
                if ($files[$file].Name.substring(4,6) -ge "<YYMMDD>") {
                    echo ("loadFile: " + $files[$file].FullName)
                    $res=loadFile($files[$file].FullName)            
                    if ( $res=$false ) {exit}

                }

            }
        }

    }
}

main

DNS Lookup

Clear-Host  
$mch=Resolve-DnsName <IP_NUMBER>  
Write-Host $mch[0].NameHost  

Module Import or Update

Find-Module -Command invoke-sqlcmd # lists which modules are required for invoke-sqlcmd 

Install-Module -Name sqlserver -Scope CurrentUser -AllowClobber     # load the modules NB scope and clobber for update
Install-Module -Name pssqllegacy -Scope CurrentUser -AllowClobber   # load the modules NB scope and clobber for update

Import-Module SqlServer  # close the session then reimport with this

SQL Varbinary Or Blob to File

NB Need to set MaxBinaryLength > than filesize e.g. 20MB = 20000000

$name  = "FileName.Extension"  
$query ="SELECT <SOME_VARBINARY(MAX)_FIELD> FROM <TABLE> `  
         WHERE X = Y"  

$binaryData = (Invoke-Sqlcmd -ServerInstance <SERVER> -TrustServerCertificate `  
                             -Query $query `  
                             -Database <DATABASE> `  
                             -MaxBinaryLength 20000000).<SOME_VARBINARY(MAX)_FIELD>

$path = ("C:\....\" + $name)   

Add-Content -Path $path -Value $binaryData -Encoding Byte  

Change Window Title

$host.ui.RawUI.WindowTitle = "New Title"  

Web Post

function postData($val) {    
    // post data    
    $postData    = @{<POST_VAR_MANE_1>=$val}    
    // data to add to header e.g a key    
    $header      = @{Key="................."}    
    // get page    
    $webReply    = Invoke-WebRequest -Uri "https://....................." `    
                      -Body $postData   `    
                      -Headers $header `    
                      -Method Post    
   // return the inner html of the first item in the 1st table.    
   return $webReply.ParsedHtml.getElementsByTagName("TD")[0].innerHTML;    
}      

Hex To ASCII

$h = "4142434445"   

-join ($h -split '(..)' | ? { $_ } | % { [char][convert]::ToUInt32($_,16) })  

Desktop Link

function addLink($name, $iconName, $path) {  
    # add if doesn't exist  
    if  ((Test-Path ("\\" + $Computer + "\" + $public + "\Desktop\" + $name).Replace(":", "$")) -eq $false) {  

        try {            

            $ShortcutFile = ("\\" + $Computer + "\" + $public + "\Desktop\" + $name).Replace(":", "$")  
            $WScriptShell = New-Object -ComObject WScript.Shell  
            $Shortcut = $WScriptShell.CreateShortcut($ShortcutFile)  
    
            $Shortcut.IconLocation = ("$env:public\Documents\" + $iconName)  
            $Shortcut.TargetPath = $path  

            $Shortcut.Save()  
        }  
        catch {  
            <FAIL_CODE>        }  
    } else {  
    <NOT_FOUND_CODE>  
    }  

}

Globals

$n = 100;  
$m = 100; 
function useGlobal() {  
    $global:n = 200;
    $m        = 200;
}  

useGlobal  
write-host $n  
write-host $m  

Outlook GetActiveObject

$Outlook = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application")

phpJSMetrics

$MAX_ROW_LEN      = 120
$HEADER_RANGE     = 10
$HEADER_MIN_CMNTS = 5

function depth ($depthString) {
    $dpth = 0
    for ($i=0 ; $i -lt $depthString.length; $i++) {
        if ($depthString[$i] -eq "{") { $dpth += 1 }
        if ($depthString[$i] -eq "}") { $dpth -= 1 }
    }
    return $dpth
}

Clear-Host
$filenames = Get-ChildItem 
$extensions = @(".php", ".htm", ".html", ".js")

foreach ( $filename in $filenames ) {

    if ($extensions.Contains( $filename.Extension ) ) {

        $fileContent = Get-Content -Path $filename

        $LINES = 0
        $LOC = 0
        $BLANK_ROWS = 0
        $COMMENT_ROWS = 0
        $IN_COMMENT = $false
        $IN_CODE_SECTION = $false
        $MAX_DEPTH = 0
        $DEPTH = 0
        $IN_FUNCTION = $false
        $FUNCTION_NAME = ""

        Write-Host ("File " + $filename)

        foreach ($row in $fileContent) {

            if ($row.Contains("<?php"   )     ) { $IN_CODE_SECTION = $true }
            if ($row.Contains("<script>")     ) { $IN_CODE_SECTION = $true }
            if ($filename.Extension -eq ".js" ) { $IN_CODE_SECTION = $true }

            # count total lines
            $LINES += 1;
            
            if ($row.Length -gt $MAX_ROW_LEN) {Write-Host ("Line $LINES greater than Max $MAX_ROW_LEN")}               

            if ($IN_CODE_SECTION) {

                # are we in a comment
                if ( $row.Contains("/*") -and ( $row.Contains("*/") -eq $false) ) {
                    $IN_COMMENT = $true   
                }
                # cout LOC 
                if ($IN_COMMENT -eq $false -and $row.Trim() -ne "") { $LOC += 1 } 

                # count blank lines
                if ($row.Trim() -eq "") { $BLANK_ROWS += 1 }

                # count comments
                if ($row.Contains("//") -or $IN_COMMENT) { $COMMENT_ROWS += 1 }

                if ( $row.Contains("*/") -eq $true ) { $IN_COMMENT = $false }
            }

            $DEPTH += depth $row
            if ( $DEPTH -gt $MAX_DEPTH ) { $MAX_DEPTH = $DEPTH }  

            if ( $row.Contains("function") -and ($IN_COMMENT -eq $false) ) {
                if ( 
                    ($row.Contains("//") -and ( $row.IndexOf("//") -gt $row.IndexOf("function")) ) -or 
                    ($row.Contains("//") -eq $false )
                    )
                {
                    $IN_FUNCTION       = $true
                    $funcStart         = $row.IndexOf("function")
                    $funcEnd           = $row.IndexOf("(",$funcStart) 
                    $FUNCTION_NAME     = $row.Substring($funcStart,$funcEnd - $funcStart)
                    $FUNCTION_DEPTH    = 0
                    $MAX_FN_DEPTH      = 0
                    $FUNCTION_ROWS     = 0
                    $FUNCTION_COMMENTS = 0
                }}
                
                if ($IN_FUNCTION) {
                    $FUNCTION_DEPTH     += depth $row
                    $FUNCTION_ROWS      += 1
                    if ($FUNCTION_DEPTH -gt $MAX_FN_DEPTH ) {$MAX_FN_DEPTH = $FUNCTION_DEPTH}                    
                    If ($IN_COMMENT -or $row.Contains("//")) {$FUNCTION_COMMENTS+=1}
                    if ($FUNCTION_DEPTH -eq 0 ) {
                        $IN_FUNCTION = $false
                        Write-Host $FUNCTION_NAME
                        Write-Host "  Function Rows $FUNCTION_ROWS"
                        Write-Host "  Function Comments $FUNCTION_COMMENTS"
                        Write-Host "  Function Depth $MAX_FN_DEPTH"
                    }
                }

            



            # check if in code section still
            if ($row.Contains("?>") -and 
                $row.LastIndexOf("<?php") -lt $row.LastIndexOf("?>")
            ) { $IN_CODE_SECTION = $false }

            if ($row.Contains("</script>") -and 
                $row.LastIndexOf("<script>") -lt $row.LastIndexOf("</script>")
            ) { $IN_CODE_SECTION = $false }

            if ($LINES -eq $HEADER_RANGE -and $COMMENT_ROWS -lt $HEADER_MIN_CMNTS) {Write-Host "Posibble Missing Header Comments"}

        }

        # output current file analysis 
        Write-Host ("Total Lines " + $LINES          )
        Write-Host ("Code Lines " + $LOC             )
        Write-Host ("Blank Lines " + $BLANK_ROWS     )
        Write-Host ("Comment Lines " + $COMMENT_ROWS )
        Write-Host ("Max Depth " + $MAX_DEPTH        )
        Write-Host ("")

    }
}
⚠️ **GitHub.com Fallback** ⚠️