Difference between revisions of "Windows Powershell"

From Ever changing code
Jump to navigation Jump to search
Line 112: Line 112:


= Download a file =
= Download a file =
== Bits transfer =
== Bits transfer ==
Windows has background service to download files. The admin console is called <code>bitsadmin</code> where equivalent Powershell cmdlets are <code>*-BitsTransfer</code>
Windows has background service to download files. The admin console is called <code>bitsadmin</code> where equivalent Powershell cmdlets are <code>*-BitsTransfer</code>
<source>
<source>
Line 129: Line 129:
$WebClient.DownloadFile("http://mirror.filearena.net/pub/speed/SpeedTest_128MB.dat","C:\tmp\file.zip")
$WebClient.DownloadFile("http://mirror.filearena.net/pub/speed/SpeedTest_128MB.dat","C:\tmp\file.zip")
</source>
</source>
= Modules =
= Modules =
Load ActiveDirectory module to have access to AD, pre-requirement to execute most commands below
Load ActiveDirectory module to have access to AD, pre-requirement to execute most commands below

Revision as of 18:05, 23 May 2019

ISE - PowerShell IDE

Untitled.ps1 - when working in ISEv2 or v4 in a script edit section, you can select code and press F8 to execute it
$_ - substitute a singular record in array
-eq, -or -and - dash means operator

Test network connection

Testing from PowerShell if NFS port on remote server is open. The test takes around 5 seconds, them prints output.

PS C:\> Test-NetConnection -ComputerName 10.1.20.1 -Port 2049
ComputerName           : 10.1.20.1
RemoteAddress          : 10.1.20.1
RemotePort             : 2049
InterfaceAlias         : Ethernet
SourceAddress          : 10.1.10.111
PingSucceeded          : True
PingReplyDetails (RTT) : 2 ms
TcpTestSucceeded       : True

PowerShell of linux commands

Tail
PS1 C:\> Get-Content -Path "C:\scripts\test.log" -Wait -Tail 100
$ tail -f /mnt/c/scripts/test.log
Curl
PS1 C:\> (Invoke-WebRequest -Headers @{"Host"="api.example.com"} -Uri http://127.0.0.1:8080 -UseBasicParsing).statuscode
PS1 C:\>  Invoke-RestMethod -Headers @{"Host"="api.example.com"} -Uri http://127.0.0.1/healthcheck                                   
$ curl --header 'Host: api.example.com' http://127.0.0.1/
Wget
#Optional enable latest TLS, by default it uses TLS1.0, use 'Ssl3' in edge cases
PS1 C:\> [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" 
PS1 C:\> Invoke-WebRequest https://github.com/Example/package.zip -OutFile package.zip
$ wget https://github.com/Example/package.zip -OutFile package.zip
Troubleshooting
Error: The request was aborted: Could not create SSL/TLS secure channel. - set SecurityProtocol

Set a hostname

<syntaxhighlightjs lang="powershell">

  1. ideally this should be up to 15 chars long to fit NetBios name otherwise it will be truncated

Rename-Computer -NewName server-1-eu -restart </syntaxhighlightjs>

Windows features

List installed features

<syntaxhighlightjs lang="powershell"> PS C:> DISM /online /get-features /format:table Deployment Image Servicing and Management tool Version: 6.3.9600.17031 Image Version: 6.3.9600.17031 Features listing for package : Microsoft-Windows-ServerCore-Package~aaaaaaaaaae35~amd64~~6.3.9600.16384


| --------

Feature Name | State


| --------

NetFx4ServerFeatures | Enabled NetFx4Extended-ASPNET45 | Enabled </syntaxhighlightjs>

Install Windows feature

nfs-client

<syntaxhighlightjs lang="powershell"> PS C:\> Get-WindowsFeature *nfs* Display Name Name Install State


---- -------------

[ ] Server for NFS FS-NFS-Service Available [ ] Client for NFS NFS-Client Available [ ] Services for Network File System Man... RSAT-NFS-Admin Available

PS C:\> Install-WindowsFeature NFS-Client -IncludeAllSubFeature -IncludeManagementTools Success Restart Needed Exit Code Feature Result


-------------- --------- --------------

True No Success {Client for NFS} </syntaxhighlightjs>


Other features, confirmed Windows Server Base 2019 | AWS <syntaxhighlightjs lang="powershell"> Install-WindowsFeature -name Web-Server -IncludeManagementTools #IIS </syntaxhighlightjs>

Install Hyper-V feature

Verified: Windows 10 Pro

Optional: Setup the Disk to allow the hypervisor <syntaxhighlightjs lang="powershell">

  1. BCDEDIT /Set `{current`} hypervisorlaunchtype auto

</syntaxhighlightjs>


Install Hyper-V feature <syntaxhighlightjs lang="powershell"> Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All #PS1 DISM /Online /Enable-Feature /All /FeatureName:Microsoft-Hyper-V #CMD </syntaxhighlightjs> Restart is required


Allow Hyper-V and VirtualBox to coexist

Hyper-V is enabled during boot process, so creating a additional BCDEDIT entry will be the solution. Open PS in Admin mode, and run as follows: <syntaxhighlightjs lang="powershell"> C:>bcdedit /copy {current} /d "Windows 10 - No hypervisor" The entry was successfully copied to {ade52f12-1207-11e9-ad93-f3c1556fc814}. C:>bcdedit /set {ade52f12-1207-11e9-ad93-f3c1556fc814} hypervisorlaunchtype off #use guid from the previous command output The operation completed successfully. </syntaxhighlightjs> In order to access the new boot menu:

  • restart and hold down shift on the keyboard while clicking Restart with the mouse
  • on a boot menu select Use another operating system > Windows 10 - No hypervisor

Download a file

Bits transfer

Windows has background service to download files. The admin console is called bitsadmin where equivalent Powershell cmdlets are *-BitsTransfer

$tmpPath="C:\tmp"
If (-Not (Test-Path $tmpPath -pathType container)) { md $tmpPath }
$tentacle_url="https://octopus.com/downloads/latest/WindowsX64/OctopusTentacle"
$tentacle_file="tentacle_install.msi"
Start-BitsTransfer -Source $tentacle_url -Destination $tmpPath\$tentacle_file
WriteOutput "BitsTransfer - success: $?"

System.Net.WebClient

A common .NET class used for downloading files is the System.Net.WebClient class.

$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile("http://mirror.filearena.net/pub/speed/SpeedTest_128MB.dat","C:\tmp\file.zip")

Modules

Load ActiveDirectory module to have access to AD, pre-requirement to execute most commands below

Import-Module -Name ActiveDirectory

Create a big file

fsutil file createnew big1k 1024       # 1Kb, filled in with Null
fsutil file createnew big1g 1073741824 # 1Gb

Schedule task

Create a schedule task that runs on a powershell script on boot, then disables itself.

$schAction = New-ScheduledTaskAction `
  -Execute "Powershell.exe" `
  -WorkingDirectory C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts `
  -Argument '-NoProfile -WindowStyle Hidden -NoLogo -NonInteractive -c "powershell .\TentacleRegister.ps1 -verbose >> .\TentacleRegisterScheduleTask.log 2>&1"'

$schTrigger   = New-ScheduledTaskTrigger   -AtStartup
$schPrincipal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest

Register-ScheduledTask -Action $schAction -Trigger $schTrigger -TaskName "RegisterTentacle" -Description "Register OctopusDeploy" -Principal $schPrincipal

#Create .ps1 script
$TentacleRegisterFileContent = @'
$TentaclePath="C:\Program Files\Octopus Deploy\Tentacle"
if (-Not (Test-Path $TentaclePath -pathType container)) { Write-Output "Octopus path not found"; exit 1 }
cd $TentaclePath
.\Tentacle.exe create-instance --instance $env:computername --config "C:\Octopus\Tentacle.config" --console
.\Tentacle.exe new-certificate --instance $env:computername --if-blank --console
.\Tentacle.exe configure       --instance $env:computername --reset-trust --console
.\Tentacle.exe configure       --instance $env:computername --home "C:\Octopus" --app "C:\Octopus\Applications" --port "10933" --console
.\Tentacle.exe configure       --instance $env:computername --trust ${tf_octopus_fingerprint} --console
netsh advfirewall firewall add rule "name=Octopus Deploy Tentacle" dir=in action=allow protocol=TCP localport=10933
$localIP=(Invoke-RestMethod http://169.254.169.254/latest/meta-data/local-ipv4)
.\Tentacle.exe register-with   --instance $env:computername `
   --server "https://deploy.contactengine.net" --apiKey="${tf_octopus_token}" `
   --role   "microservices" --environment "${tf_octopus_environment}" `
   --comms-style TentaclePassive -h $localIP --force --console
.\Tentacle.exe service --instance $env:computername --install --stop --start --console

#Disable/delete scheduled task
#Unregister-ScheduledTask -TaskName "RegisterTentacle" -Confirm:$false
Disable-ScheduledTask     -TaskName "RegisterTentacle"
'@

What is worth to note re-direction -Argument '-NoProfile -WindowStyle Hidden -NoLogo -NonInteractive -c "powershell .\TentacleRegister.ps1 -verbose >> .\TentacleRegisterScheduleTask.log 2>&1"' that allows to log execution STD and STDERR to a file. Please note that most of the schedule task scripts run in SYSTEM user context. Then it's also important that the task name match here RegisterTentacle

Extract from Active Directory

<syntaxhighlightjs lang="powershell"> get-aduser -Filter {Samaccountname -eq "Smith"} -properties Organization get-aduser -Filter {(Givenname -eq "Smithy") -and (Surname -eq "Smith")}

  1. Build array $users with all Samaccountname(loginnames) with additional properties: Name, Description

$users = get-aduser -Filter {Samaccountname -like "*"} -properties Name, Description

  1. Return array object count

$users.count

  1. Search array $users where $_ each object in array field samaccountname has a given string

$users | Where-Object {$_.samaccountname -eq "string_to_compare"}

  1. Build array of enabled and disabled accounts in AD where field Enabled equal $true ($true boolean is 1 $false is 0)

$enabledusers = $users | Where-Object {$_.Enabled -eq $true } $disabledusers = $users | Where-Object {$_.Enabled -eq $false}

  1. Filter array $disabledusers returning only Samaccountname, GivenName, Surname and display (ft = Format-table)

$disabledusers | Select-Object Samaccountname, GivenName, Surname | ft -AutoSize

  1. Build create new array from filter of $users array if name or description contains a string

$aausers = $users | Where-Object {( $_.Name -like "*aa*") -or ($_.Description -like "*bb*")} $aausers | Select-Object Samaccountname, GivenName, Surname, Enabled | Sort-Object Enabled | ft -AutoSize

  1. Print a table with records matching $aauser if another AD account has the same name and surname

foreach ($aauser in $aausers) {

 $realuser = [array](get-aduser -Filter {((Givenname -eq $aauser.Givenname) -and (Surname -eq $aauser.Surname))}) 
 write-host $aauser.samaccountname "|" $aauser.name "|"  $aauser.enabled "|"$realuser[0].SamAccountname "|"$realuser[0].GivenName"|" $realuser[0].Surname"|" $realuser[0].Enabled

}

  1. Build array with GivenName, Surname that match filter of: Enabled field is false (disabled account)

$temp = Get-ADUser -Properties GivenName, Surname -filter {Enabled -eq $false}

  1. Export the array to CSV file

$temp | Export-Csv temp.csv </syntaxhighlightjs>

AD Extract 2

$reportdate = Get-Date -Format yyyyMMdd-HHmm 
$csvreportfile = "ADUsers-extract-$reportdate.csv" 
Get-ADUser -SearchBase "OU=Users,DC=corp,DC=local" -Filter * -ResultSetSize 5000 | Get-ADUser -Properties * | 
          select SamAccountName,EmailAddress,Givenname,Surname,Title,Department,Enabled | 
          Export-Csv -Path $csvreportfile -NoTypeInformation

Create users from csv

Csv file BulkAddADUsers.csv

Name,GivenName,Surname,SamAccountName,UserPrincipalName,EmailAddress,AccountEnabled,AccountPassword,PasswordNeverExpires,Path
Full Name,Firstname,Surname,fsurname,fsurname@example.com,fsurname@example.com,$true,PassWord123,$true,"OU=Users,OU=Testing ,OU=USA,DC=corp-example,DC=io"

BulkAddADUsers.ps1 <syntaxhighlightjs lang="powershell">

  1. CSV headline: Name,GivenName,Surname,SamAccountName,UserPrincipalName,EmailAddress,Enabled,AccountPassword,PasswordNeverExpires,Path
  2. Script - CSV headline
  3. Name - first+last name
  4. GivenName - first name
  5. Surname - last name
  6. SamAccountName - username
  7. UserPrincipalName - it is user-logon-name, where you need to choose domain, eg. test@example.com or @corp-example.io
  8. Path - object location, use get-aduser <SamAccountName>

Import-Csv .\BulkAddADUsers.csv | % { ` New-ADUser -Name $_.Name -GivenName $_.GivenName -Surname $_.Surname -SamAccountName $_.SamAccountName `

 -UserPrincipalName $_.UserPrincipalName -EmailAddress $_.EmailAddress `
 -Enabled $true -AccountPassword (ConvertTo-SecureString $_.AccountPassword -AsPlainText -force) `
 -PasswordNeverExpires $true -Path $_.Path

}

  1. errors
  2. -Enabled cannot read $true value from CSV therefore it has been hard coded

</syntaxhighlightjs>

Get membership of a user

Get-ADPrincipalGroupMembership username| select name

IIS - create a website

Tested on Server 2012 R2 Data Centre in Azure <syntaxhighlightjs lang="powershell"> $SiteName = "WWW" $AppPoolName = "WWWAppPool" $SiteFolder = Join-Path -Path 'C:\inetpub\wwwroot' -ChildPath $SiteName $LogDir = "d:\Logs\iis_logs\$SiteName" $HostHeader = "www.example.com"

Import-Module WebAdministration

  1. create appPool

if(-Not (Test-Path IIS:\AppPools\$AppPoolName)) { New-WebAppPool -Name $AppPoolName -Force }

  1. create Site

if(-Not (Test-Path $SiteFolder -pathType container)) { md $SiteFolder } New-WebSite -Name $SiteName -PhysicalPath $SiteFolder -Force -ApplicationPool $AppPoolName Get-WebBinding -Name $SiteName -Port 80 | Remove-WebBinding New-WebBinding -Name $SiteName -Protocol http -Port 80 -IPAddress * -HostHeader $HostHeader New-WebBinding -Name $SiteName -Protocol http -Port 8080 -IPAddress * -HostHeader $HostHeader

  1. Logging dir

if (-Not (Test-Path $LogDir -pathType container)) { md $LogDir } Set-ItemProperty "IIS:\Sites\$SiteName" -name logFile.directory -value $LogDir Start-WebSite -Name $SiteName </syntaxhighlightjs>

File content

<syntaxhighlightjs lang="powershell"> $hostsFileContent = @" 127.0.0.1 example.com 127.0.0.1 example.local "@

Add-Content -Path "c:\Windows\System32\drivers\etc\hosts" -Value $hostsFileContent Set-Content -Path "c:\Windows\System32\drivers\etc\hosts" -Value $hostsFileContent </syntaxhighlightjs>

References