Published on

PowerShell and Commands

Authors
  • Name
    Jackson Chen

PowerShell 7.2

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/new-localuser?view=powershell-5.1

Linux equivalent Windows Commands

findstr     # grep
ping test
  1. sysinternal tools - psping The target can be ip or dns name of Virtual Machine, Storage, SQL Database and other endpoints that is accessible

https://docs.microsoft.com/en-us/sysinternals/downloads/psping

https://blog.cadena-it.com/window-tips/psping-example/

PsPing - Test ping, latency and bandwidth

PsPing Test ping latency and bandwidth

# TCP ping test
psping -n 100 -i 0 <target-ip>
    -n 100      Number of pings, or append 's' to specify ping time, such as '10s'
    -i 0        Interval in seconds. Sperficy '0' for fast ping
    Example
        psping www.google.com:80
        psping -n 100 -i 0 www.google.com:80

psping -n 100 -i 0 <target-ip>:<port>
    <port>      Non-standard ICMP port

#******* Test latency and bandwidth ***********
# Configure source endpoint
    using specific port, rather than ICMP port
1. On target server start/setup a listening service and establish the connect from source to this service port
c:\windows\systems32\psping -4 -f -s <local-ip>:<listening-port>
    -4  IPv4
    -f  open Windows firewall (if required)
    -s  service

# Latency test - TCP port
2. On source/testing system
psping -4 -h 10 -n 10 -l 1000 <target-ip>:<target-listening-port>
    -h      Create a histogram of 10 buckets
    -n 10 -l 1000  # Use 10 packets of 1000 bytes each
    -n 10 -l 10M   # Use 10 packets of 10MB each

# Latency test - UDP port
3. Test udp
psping -u -4 -f -s <local-ip>:<listening-port>      # Target system    
psping -u -4 -h 10 -n 10 -l 1000 <target-ip>:<target-listening-port>

# Bandwidth test
    Test latency first, after successful latency test and verify result, then test bandwidth 
4. Bandwidth test
psping -b -4 -l 2M -n 10s <target-ip>:<target-listening-port>
    -b      Bandwidth test
    -4      IPv4
    -l 2M -n 10s    # Use 10 packets of 2M each
            -l 100m -n 10   # test 100M each
  1. ping and safe result to log file
ping.exe -t <dest> -l 1450 | ForEach-Object {"{0} - {1}" -f (Get-Date),$_} | Tee-Object C:\Temp\<logname>.ping.log –Append

hrpings

https://www.cfos.de/en/ping/ping.htm

# Features
1. Graphical display of ping results
2. Uses high resolution timers, so ping times are accurate to the usec
3. Can ping as well with UDP packets or ICMP timestamp messages
4. Times and handles ICMP error replies as well
5. Can have multiple pings "in-flight", no need to wait for a reply before sending the next ping
6. Improved statistics
7. Size sweep: Send increasing packet sizes
8. Can show only a summary of results
9. Is a Traceroute and a Pathping as well

Local Users and Groups with PowerShell

https://blog.netwrix.com/2018/09/18/how-to-add-delete-and-change-local-users-and-groups-with-powershell/

https://techcommunity.microsoft.com/t5/itops-talk-blog/how-to-manage-local-users-and-groups-using-powershell/ba-p/733544

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.localaccounts/new-localuser?view=powershell-5.1

Create folder on remote system

# Method 1
function createNewRemoteFolder($newFolderPath) {

    $scriptStr = "New-Item -Path $newFolderPath -type directory -Force"
    $scriptBlock = [scriptblock]::Create($scriptStr)

    runScriptBlock $scriptBlock
}


function runScriptBlock($scriptBlock) {

    Invoke-Command -ComputerName $server -Credential $MySecureCreds -ScriptBlock $scriptBlock
}

# Method 2
UNC path works as well with New-Item

$ComputerName = "fooComputer"
$DriveLetter = "D"
$Path = "fooPath"
New-Item -Path \\$ComputerName\$DriveLetter$\$Path -type directory -Force 


# Method 3
$Company = Read-Host 'Enter Company Name:'
$Credentials = Get-Credential

Write-Host 'Thank you! Creating client FTP folder on ServerA.' -ForegroundColor Magenta -BackgroundColor White 

Invoke-Command ServerA {mkdir ("e:\ftp\users\" + $args[0] + "\INCOMING")} -ArgumentList $Company -Credential $Credentials
Invoke-Command ServerA {mkdir ("e:\ftp\users\" + $args[0] + "\OUTGOING")} -ArgumentList $Company -Credential $Credentials

Write-Host 'Done. Now creating duplicate folder on ServerB.' -ForegroundColor Magenta -BackgroundColor White 

Invoke-Command ServerB {mkdir ("e:\ftp\users\" + $args[0] + "\INCOMING")} -ArgumentList $Company -Credential $Credentials
Invoke-Command ServerB {mkdir ("e:\ftp\users\" + $args[0] + "\OUTGOING")} -ArgumentList $Company -Credential $Credentials

Write-Host 'Done.' -ForegroundColor Magenta -BackgroundColor White 

Update folder ACL

https://petri.com/how-to-use-powershell-to-manage-folder-permissions/

https://blog.netwrix.com/2018/04/18/how-to-manage-file-system-acls-with-powershell-scripts/

Get-ACL -Path "Folder1").Access | Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited,InheritanceFlags -AutoSize


# Process
1. Retrieve the existing ACL rules
$ACL = Get-ACL -Path "Folder1"      
    # get-acl \\fs1\shared\sales | fl

2. Craft a new FileSystemAccessRule to apply
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("domain\Group1","Modify","Allow")

3. Add the new ACL rule on the existing permission set
$ACL.SetAccessRule($AccessRule)

4. Apply the new ACL to the existing file or folder
$ACL | Set-Acl -Path "Folder1"
    # $ACL | Set-Acl -Path "\\fs1\shared\folder1"

5. Verify ACL changes
(Get-ACL -Path "Folder1").Access | Format-Table IdentityReference,FileSystemRights,AccessControlType,IsInherited,InheritanceFlags -AutoSize

DFS with PowerShell

https://adamtheautomator.com/dfs-powershell-scripts/

https://docs.microsoft.com/en-us/powershell/module/dfsn/new-dfsnfolder?view=windowsserver2022-ps

# List DFS Namespaces
$Domain = 'test.lab'
(Get-DfsnRoot -Domain $Domain).Where( {$_.State -eq 'Online'} ) | Select-Object -ExpandProperty Path

# List DFS folders
Get-DfsnFolder -Path "\\$Domain\Apps\*" | Select-Object -ExpandProperty Path
#**************** Example
$Domain = 'test.lab'
try {
    Get-DfsnFolderTarget -Path "\\$Domain\Apps\PowerShell" -ErrorAction Stop
} catch {
    Write-Host "Path not found. Clear to proceed" -ForegroundColor Green
}

$NewDFSFolder = @{
    Path = "\\$Domain\Apps\PowerShell"
    State = 'Online'
    TargetPath = '\\datacenter\FileShare\PowerShell'
    TargetState = 'Online'
    ReferralPriorityClass = 'globalhigh'
}

New-DfsnFolder @NewDFSFolder

# Check that folder now exists:
Get-DfsnFolderTarget -Path "\\$Domain\Apps\PowerShell"

# Check that the new DFS Link works using Windows Explorer
Invoke-Expression "explorer '\\$Domain\Appst\PowerShell\'"


# Add DFS Folder Targets
$Domain = 'test.lab'

## Splat the settings for easy readibility
$NewTPS = @{
    Path = "\$Domain\AppRoot\PowerShell"
    TargetPath = '\FileServer01\FileShare\PowerShell'
    State = 'Online'
}

## Add new folder located on the 'FileServer01' server & set Online
New-DfsnFolderTarget @NewTPS

## Removing DFS folder target paths
# Check Target Path to 'FileServer01' server to Offline & Remove the Folder Target Path
if ((Get-DfsnFolderTarget -Path "\\$Domain\AppRoot\PowerShell" -TargetPath '\\FileServer01\FileShare\PowerShell').State -eq "Offline") {
    Remove-DfsnFolderTarget -Path "\\$Domain\AppRoot\PowerShell" -TargetPath '\\FileServer01\FileShare\PowerShell' -Force:$true
}


## Delete DFS folder target
## Splatting the settings where the path pointed at the server named 'FileServer02'
$DelFTS = @{
    Path = "\$Domain\AppRoot\PowerShell"
    TargetPath = '\FileServer02\FileShare\PowerShell'
}

##Delete the DFS FolderTarget
Remove-DfsnFolderTarget @DelFTS -Force:$true


## Delete the DFS Folder
Remove-DfsnFolder -Path "\$Domain\AppRoot\PowerShell" -Force:$true

DFS folder Access Based Enumeration (ABE) using PowerShell

https://docs.microsoft.com/en-us/windows-server/storage/dfs-namespaces/enable-access-based-enumeration-on-a-namespace

# Check ABE on share folder
Get-SmbShare <share-folder> | FL *
Get-SmbShare <share-folder>  |Select-Object Name, FolderEnumerationMode

# To enable ABE for a specific folder
Get-SmbShare <share-folder> | Set-SmbShare -FolderEnumerationMode AccessBased

Set-DfsnRoot -Path \\frankfu\share -EnableAccessBasedEnumeration $true


# To disable ABE
Get-SmbShare Install | Set-SmbShare -FolderEnumerationMode Unrestricted

Note:
    dfsutil property abde enable \\namespace_root


#********
# To control folder visibility by using a command line
# Open Command prompt on a server that has DFS role or DFS Tools feature installed
dfsutil property sd grant \\contoso.office\public\training "CONTOSO\Domain Admins":RX CONTOSO\Trainers:RX Protect Replace

# Alternative
Start-Process -FilePath "C:\Windows\system32\dfsutil.exe" 
    -ArgumentList "property sd grant \\contoso.office\public\training `"CONTOSO\Domain Admins`":RX CONTOSO\Trainers:RX Protect"

# This works
$DFS_folder = "\\domain.com\group\folder"
$Group_domainname_string = $domain + "\" + $GroupName # GroupName can contain space
# Need to escape "`"" and ":RX`"" for DFS command
$DFScmd = "`"" + $Group_domainname_string + ":RX`""
Start-Process -FilePath "C:\Windows\system32\dfsutil.exe" -ArgumentList "property SD grant $DFSroot $DFScmd protect" -wait

Start-Process

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-7.2

The Start-Process cmdlet starts one or more processes on the local computer. By default, Start-Process creates a new process that inherits all the environment variables that are defined in the current process.

To specify the program that runs in the process, enter an executable file or script file, or a file that can be opened by using a program on the computer. If you specify a non-executable file, Start-Process starts the program that is associated with the file, similar to the Invoke-Item cmdlet.

You can use the parameters of Start-Process to specify options, such as loading a user profile, starting the process in a new window, or using alternate credentials.

Specifying arguments to the process

Both commands start the Windows command interpreter, issuing a dir command on the Program Files folder. Because this foldername contains a space, the value needs surrounded with escaped quotes. Note that the first command specifies a string as ArgumentList. The second command is a string array.

Start-Process -FilePath "$env:comspec" -ArgumentList "/c dir `"%systemdrive%\program files`""
Start-Process -FilePath "$env:comspec" -ArgumentList "/c","dir","`"%systemdrive%\program files`""
Using the PowerShell Invocation Operator &

we can call the Invocation operator or the ampersand sign & at the start of the command line to run the executable path in Windows PowerShell properly.

& "C:\Program Files\AVAST Software\Avast\ashCmd.exe" /Quick
DFSN Module

https://docs.microsoft.com/en-us/powershell/module/dfsn/?view=windowsserver2022-ps

Run PowerShell script as administrator
# Check if session is elevated
[bool]$isElevated = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)

if ($isElevated)
{
    Write-Host 'Session is elevated'
}
else
{
    # Start a new elevated PowerShell session
    Start-Process -FilePath PowerShell.exe -Verb Runas
}
Elevate PowerShell session as another user
Start-Process powershell.exe -Credential "Domain\User1" -ArgumentList "Start-Process powershell_ise.exe -Verb RunAs"

Robocopy source or destination folder has SPACE

When the source or destination path has SPACE character, need to using single quote to enclose the path string

# Variables
$Date = Get-Date -Format "yyyy-MM-dd"
$timestamp = Get-Date -UFormat "%d/%m/%Y %R"
$datestamp = Get-Date -UFormat "%d/%m/%Y"

$Computer = $env:COMPUTERNAME
# Initial Copy - copy NTFS security permission
$options = "/E /MT:16 /NP"

<#
# Final delta sync
$options = "/XO /E /MT:16"
#>

$date = Get-Date
$minute = (Get-Date -Format yyyy.MM.dd.hh.mm)
$LogFile = "\\$Computer\C$\Operations\Logs\Folder-Migration-$Computer-$minute.txt"

$SourcePath = `\\<SourceServerName>|<DomainName>\testing\test folder only`
$DestPath = `\\<DestServerName>|<DomainName>\NewFolder\test folder only`

 Try {
    # Verify the validity of the source path
    If (Test-Path $SourcePath) {
        # Verify the validity of the destination path
        If (Test-Path $DestPath) {
            Invoke-Expression "robocopy $SourcePath $DestPath $options /log:$LogFile" -ErrorAction Stop
            Write-Host "`tRequired files have been copied." -ForegroundColor Green
        }
        Else {
            Write-Host "`tThe destination path is not the valid destination folder. Please verify." -ForegroundColor Yellow
        }                
    }
    Else {
        Write-Host "`tThe source path is not valid. Please verify and try again." -ForegroundColor Red
    }  
}          
Catch {
    # Inform support team that the file migration has failed
    Write-Host "`nNot able to migration files and folders, please try again." -ForegroundColor Red
}

Abstract user attributes

To list all the user active directory attributes

# Using "-Property *" to list all attributes
Get-ADUser -Identity <username> -Property *