Powershell - auto-mate/CheatSheetWiki GitHub Wiki
- $PS variables
- Active Directory and LDAP
- API Calls to Close JS Message
- Arrays
- Args
- Bypass Policy
- Cast Convert
- Close all ie browsers and open new ie as object
- Clipboard
- Com Items List
- Cmd Dos use in PS sheduled tasks backup
- Date
- Delete Files By Date
- Desktop Link
- Dir
- DNS Lookup
- Dot Sourcing i.e. include another ps1 file
- dotnet
- Drive Space
- Env Variables
- Excel
- Exit
- File Is Locked check
- File System Watcher
- For
- ForEach-Object example line count in files
- Form - Simple
- Functions
- Globals
- HEAD
- Hex To ASCII
- Here Strings C Sharp Example
- if
- iis Logs
- import
- Kill by Window Title
- Module Import or Update
- Open A File And Read Lines
- Open File and Read (Skip N Lines)
- Open File and Read (Skip X Lines :: Read Only First Y Lines)
- Open File and Read (Skip X Lines :: Read Only First Y Lines :: Ignore Lines Matching a Simple Pattern)
- Open A File And Write
- Orphaned Processes
- Outlook Not Spam Confirmation
- Outlook GetActiveObject
- Parse Text
- Parse Program For SAP Reports
- phpJSMetrics
- Pipes
- Ping Port
- Reference
- SAP Automation
- Scriptblock
- Secure String
- Set Working Directory
- Start-Process
- Snippets ISE Only
- SQL
- SQL With Secure String
- SQL Varbinary/Blob to File
- Top
- User Input - Simple
- VB dotnet
- Web Post
- Change Window Title
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"
$z=[system.io.driveinfo]("C:\")
$z.TotalFreeSpace/(1024*1024*1024) # OR write-host ($z.TotalFreeSpace/(1024*1024*1024))
# 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()
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";
# 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)
$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
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$title = 'Some Title'
$msg = 'Some Info:'
$text = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)
Write-Output $text
$file='C:\temp\file.txt'
$reader = New-Object -TypeName System.IO.StreamReader -ArgumentList $file
while ($x=$reader.readline()) {
echo $x # "OR" Write-Host $x
}
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
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
#>
$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()
$toParse = "123,45,OK,31,70,FAIL,2"
$l=$toParse.split(",")
for ($n = 0 ;$n -lt $l.length;$n++) {
Write-Host $l[$n]
}
<#
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('~');
[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
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
$VarName=Get-Date
$Yesterday=Get-Date.AddDays(-1)
# Formated Date $FmtDate = get-date -Format "yyyyMMdd_HHmmss"
Get-ChildItem -File -Filter *PartOfFileNameToLookFor* -Path "C:\Some\Path\" -Recurse
NB -LT,-LE,-GT,-GE,-EQ
IF ($x -LT $y) {Write-Output $date.Year}
NB -LT,-LE,-GT,-GE,-EQ Exit with {Break}
for ( $n=0; $n -LT 10; $n++ ) {
Write-Output $n
}
Test-NetConnection <IP> -port <PORT>
Get-Process | Where-Object {$_.MainWindowTitle.Contains("<PART_OF_WINDOW_TITLE>")} | stop-Process
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.
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";
}
}
}
}
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
<# 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
Input params to powershell file
$someVar=$args[0];
ctrl+J
require unrestricted policy
kept in $home\Documents\WindowsPowerShell\Snippets edit and delete as required
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 (stays till ISE re-opened)
Get-IseSnippet | Where-Object -Property Name -like "ForLoop*" | Remove-Item
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)
# 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
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);
}
#>
$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"
}
}
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 ;
}
}
}
Get-Content -first 10
$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; }
# 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];
}
}
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
$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"
$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;
# optional -Append
echo $someString | Out-File -Encoding <OPTIONS> -FilePath <PATH>
To use .net methods enter as below
Enter as [Namespace.Class]::Method
function waitTillFileUnLocked($fileName) {
$loopEnd="f"
while ($loopEnd -eq "f") {
Wait-Event -Timeout 1
try{
[System.IO.File]::OpenWrite($fileName).close();
$loopEnd="t"
} catch {}
}
}
Set-Location -path $PSScriptRoot
To load a function in external file in the current file
. .\<filename.ps1>
. .\<SomeFolder>\<SomeFile.ps1>
# 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"
}
Various data is available in $PS variables e.g. $PSVersionTable , $PSCulture, $PSEdition, $PSHOME, $psISE, $PSSessionApplicationName, $PSSessionConfigurationName, $PSSessionOption, $PSUICulture, $psUnsupportedConsoleApplications
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!
Plenty of Environment Variables e.g. $env:USERNAME
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();
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
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
Use -pasthru to return an object that has info about the process created!
use -as to convert type e.g.
$n = "1" -as [long];
$n.GetType();
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>}
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
#>
# 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
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 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"
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))
Exits a script
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
Clear-Host
$mch=Resolve-DnsName <IP_NUMBER>
Write-Host $mch[0].NameHost
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
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
$host.ui.RawUI.WindowTitle = "New Title"
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;
}
$h = "4142434445"
-join ($h -split '(..)' | ? { $_ } | % { [char][convert]::ToUInt32($_,16) })
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>
}
}
$n = 100;
$m = 100;
function useGlobal() {
$global:n = 200;
$m = 200;
}
useGlobal
write-host $n
write-host $m
$Outlook = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application")
$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 ("")
}
}