PoSh: No GUI 4 U – Server Administration

“I need to know how to do my job and perform certain task”   When it comes to PowerShell this is the most common request I get around PowerShell training topics.  As admins continue to struggle with the decision on whether they use a GUI on Windows Server or to use Core, I want to provide the most basic cmdlets and resources that one would need to administer Windows Server successfully.   This blog entry wont go into the why I think everyone should move to Windows Server Core or why I think everyone needs to learn PowerShell as a scripting language. 

If you would like to learn more about PowerShell and if the company you work for is a Microsoft Premier Customer, reach out to the Technical Account Manager assigned to your company and look into setting up one of Premier’s Workshop around PowerShell.

 

if you’ve attended one of my brown bags  or Tech Talks around GUI ‘less administration, here is the cmdlets used during those sessions.

All the example cmdlets were tested on a Windows 10 client host using PowerShell direct to the host. They also work the same way performing windows to windows remote pssessions.

PowerShell Direct – Running PowerShell inside a virtual machine from the Hyper-V host

 

Most Useful Cmdlets

 #use this to get help for a particular cmdlet
 get-help get-help
  
 #Powershell 5 updates are needed to view help, save help files on host.
 save-help -Module * -DestinationPath c:\data\save
     #on vm create folder to save help files to
     New-Item .\save -ItemType directory
     #on host, copy files through the psession to the vm
     copy-item -ToSession $localvm -Path c:\data\save\* -Destination c:\data\save
 #on vm, update help on vm server
 Update-Help -SourcePath c:\data\save
  
 get-help Get-Service
 get-help get-service -Examples
 get-help get-service -Detailed
 get-help get-service -Full
  
 #will provide help on any particular powershell topic
 get-help "about_variable"
 get-help about_*
  
 #find cmdlets based on certain criteria
 get-command -name *service*
 get-command -Verb get
 get-command -noun service
 get-command -verb get -noun *service*
 get-command -ParameterName computername
 get-command -ParameterName ciminstance
 get-command -Module Microsoft.PowerShell.Management
  
 #find cmdlets in a module
 get-command -module storage
  
 #get information about an object, or objects cmdlets return
 #get-help about_types
 Get-Member
 get-service | Get-Member
 get-service | Get-Member -MemberType Property 
 get-service | Get-Member -MemberType Method 
     
 #find info about an array
 ,$(get-service) | get-member
  
 #alias's are used to simplify or common name cmdlets
 #get-help about_alias
 Get-Alias
 Get-Alias dir
     
 #Execution policy defines how cmdlets and scripts can be ran remotly and locally
 #get-help about_Execution_Policies
 Get-ExecutionPolicy
 Get-ExecutionPolicy -List
 #can use gpo or similar cmdlet to change.
 Set-ExecutionPolicy -ExecutionPolicy Unrestricted
  
 #displays every performed during a session
 #get-help about_history
 get-history
 #create a script based on the activity you have done
 (Get-History).commandline | Out-File c:\data\examplescript.ps1
 #review the results
 psedit C:\data\examplescript.ps1

Five Best PowerShell Cmdlets

PowerTip: Find Array Members with Get-Member in PowerShell

Is it safe to use ALIASES in scripts?

Weekend Scripter: Looking at PowerShell Aliases

PowerShell Modules

 #get-help about_modules
 #get-command *module
  
 Get-Module
 get-module -listavailable
 import-module activedirectory #if module is installed on newer ps version not needed
  
 #get all available modules and import them.  This is useful for get-command
 get-module -ListAvailable | Import-Module
  
 #check the Powershell gallery for a module
 find-module azuread
 find-module azuread | install-module

Welcome to the PowerShell Gallery

Overview of the PowerShell Get module to find scripts

Features and Roles

 #get-command *WindowsFeature*
 #get-help Get-WindowsFeature
  
 #get all windows features, format it to make it more readable
 Get-WindowsFeature
 Get-WindowsFeature | select displayname,name, installstate, Installed
  
 #just installed features
 Get-WindowsFeature | where installed -eq $true | select displayname,name, installstate, Installed
  
 #install the file service role
 get-windowsfeature File-Services | Install-WindowsFeature
 Get-WindowsFeature *file*
     
 #install the rsat feature
 Get-WindowsFeature *rsat* 
 get-windowsfeature rsat | Install-WindowsFeature
  
 Get-WindowsFeature | where installed -eq $true | select displayname,name, installstate, Installed

 

Useful Windows Feature Commands

Server Rename, Shutdown, Restart and Domain Joining

 #get-command *-computer*
  
 #get a consolidated view of system and os properties
 get-computerinfo
  
 #rename a computer
 rename-computer -NewName server1
  
 #join a computer to Active Directory and Rename it
 add-computer -NewName server1 -DomainName contoso.com
  
 #test and repair secure channel between computer and domain
 Test-computersecurechannel
 Test-ComputerSecureChannel -Repair
  
 #Resets the machine account password for the computer
 Reset-computermachinepassword
  
 #restart and shutdown
 restart-computer
 stop-computer

Use PowerShell to Reset the Secure Channel on a Desktop

CIM – WMI

CIM and WMI is an entire session in its self, going to provide some useful links for you to read up on.  The bottom line is wmi cmdlets and cim cmdlets have their uses.  But learing to leverage cimcmdlets will simplify task

 #get-help about_WMI
 #get-help about_cimsession
 #get-command *cim*
 #get-command *wmi*
  
 Get-CimClass *service*
 Get-wmiobject -list *service*
     
 #get services running
 Get-CimInstance Win32_Service | where state -eq "running"
     
 #get account service running under
 Get-CimInstance Win32_Service | select name, startname
  
 #cimsession use wsman instead of dcom, cimsession can use dcom though. A CIM session is a client-side object representing a connection to a local or remote computer. 
 #The CIM session contains information about the connection, such as ComputerName, the protocol used for the connection, session ID, and instance ID.
 get-command -ParameterName cimsession

CIM Cmdlets – Some Tips & Tricks

Remoting Week: Remoting Recap

Remoting the Implicit Way

Introduction to CIM Cmdlets

Should I use CIM or WMI with Windows PowerShell?

Comparing CIM and WMI in PowerShell

Using PowerShell CIM Cmdlets to Explore WMI Classes

Part 1 – Install Bash on Windows 10, OMI CIM Server, and DSC for Linux

Extending Inventory on Linux and UNIX computers using Open Management Infrastructure (OMI)

Services and Processes

 #get-help get-service
 #get-command *-service
     
 Get-Service
 get-service -name w32time
 get-service -name w32time | Stop-Service
 get-service -name w32time | start-Service
 get-service -name w32time | restart-Service
  
 #get-help get-process
 #get-command *-process
  
 Get-Process
 get-process lsass
 Start-Process notepad
 Get-Process notepad
 get-process notepad -includeusername
 get-process notepad -includeusername | select name,username,description,Id,path,ProcessName,fileversion,Handles,NPM,PM,WS,VM,CPU
 Get-Process notepad | Stop-Process

The Scripting Wife Uses PowerShell to Find Service Accounts

Use PowerShell to Find Non-Starting Automatic Services

Three Cool PowerShell Service Tricks

Get Process Owner and Other Info with WMI and PowerShell

Use PowerShell to Explore Process Threads in Windows

Local User and Local Groups

 #get-command *localuser
 #get-help get-localuser
  
 #new for Windows 10/2016 WHAT!!!!!
 Get-LocalUser
 New-LocalUser -Name Chunk  -Password (ConvertTo-SecureString -AsPlainText P@ssw0rd -Force)
 Get-localuser -Name administrator | Set-LocalUser -Password (ConvertTo-SecureString -AsPlainText P@ssw0rd -Force)
  
 #get-command *localgroup*
  
 Get-LocalGroup
 Get-LocalGroupMember administrators
 Add-LocalGroupMember -Member "Chunk" -Name administrators
  
 #old wmi/cim
 Get-CimInstance win32_useraccount -filter "domain='$env:computername'“
  
 #really old way WINNT Provider using adsi
 $machine = [ADSI]"WinNT://$env:COMPUTERNAME"
 $machine | get-member
 $machine.Children | where schemaclassname -eq "user" | select *
 $machine.Children | where schemaclassname -eq "user" | Select name
 $user = $machine.create("User","Larry")
 $user.setpassword("Directory1")
 $user.setinfo()

Adding Local Users to Local Groups

Use PowerShell to Add Local Users to Local Groups

Use PowerShell to Create Local Groups

How Can I Use Windows PowerShell to Determine the Status of the Guest Account?

Files and Folders

 #Providers and drives first, A Windows PowerShell provider allows any data store to be exposed like a file system as if it were a mounted drive.
 #get-help about_provider
 get-psprovider
 #get-command
 #get-help *psdrive*
 get-psdrive -PSProvider FileSystem
  
 #does a file exist or not
 test-path c:\data
  
 get-command *item* -Module Microsoft.PowerShell.Management
  
 #list files and subfolders
 Dir
 Get-Alias dir
 Get-ChildItem -Recurse
  
 #change directory
 Get-Alias cd
 set-Location
  
 #filter for file types
 get-childitem C:\windows\system32 -recurse |  where {$_.extension -eq ".dll"} | select Directory,name,extension
 get-childitem C:\windows\system32 -recurse |  where {$_.extension -eq ".sys"} | select Directory,name,extension
  
 #create a bunch of generic files
 1..20 | foreach{new-item ".\test$($_).txt" -itemtype file}
  
  
 psedit .\test1.txt
 Get-Content .\test1.txt
  
 #create a folder
 New-Item .\move -ItemType directory
 New-Item .\copy -ItemType directory
 dir
  
 #move
 move-item -Path .\test10.txt -Destination .\move
 copy-item -Path .\test11.txt -Destination .\copy
 cd .\move
 dir
 cd .\copy
 dir
 cd..
  
 #delete
 remove-item  -Path .\test11.txt
  
 #copy an item through pssession/powershell direct
 Copy-Item -FromSession $session -Path c:\data\* -Destination c:\data\

Learn How to Use the PowerShell Env: PSDrive

Playing with the AD: Drive for Fun and Profit

Working with Certificates in PowerShell

Use PowerShell to Work Easily with Drives and Paths

Hey scripting guys providers

Shares

 #get-command *smb*
 #get-help get-smbshare
  
 #get a list of smb shares
 Get-smbshare
  
 #see more info
 Get-SmbShare | select *
  
 #create a new share give account read access
 new-smbshare -name "User_File_Share" -path "c:\data\share" -readaccess "corp\blah"
  
 #add additional access to a share
 Grant-SmbShareAccess -Name "User_File_Share" -AccountName corp\chad -AccessRight Full
  
 #find all smb shares with file in its name
 Get-smbshare "*file*" | select *
 #list open files on shares
 Get-SmbOpenFile
  
 #How to map a drive using psdrive
 New-PSDrive -Name "P" -PSProvider "FileSystem" -Root "\\Server01\Public"
  
 New-SmbMapping -LocalPath X: -RemotePath "\\Server01\Public"
 Remove-SmbMapping -LocalPath X:

The basics of SMB PowerShell, a feature of Windows Server 2012 and SMB 3.0

The built-in SMB PowerShell aliases in Windows Server 2012 and Windows 8

Registry

 get-psdrive -PSProvider Registry
     
 #use Get-Item. Registry keys have a property with the generic name of "Property" that is a list of registry entries in the key
 #get-command *item* -Module Microsoft.PowerShell.Management
 #get-help get-item
 Get-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion
 Get-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion | Select-Object -ExpandProperty Property
  
 #get-help get-childitem
 Get-childItem HKLM:\System\CurrentControlSet\Services\Tcpip 
  
 Get-childItem HKLM:\System\CurrentControlSet\Services\Tcpip -Recurse
     
 Get-childItem HKLM:\System\CurrentControlSet\Services\Tcpip -Recurse  -PipelineVariable hive | foreach{$hive.name;$hive | Get-ItemProperty}
     
 #A little more readable with get-itemproperty
 Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\Tcpip
 Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion
     
 #Create
 New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name Thisisatest -PropertyType String -Value yep
     
 #delete
 Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name Thisisatest
  
 #leverage invoke-command to perform remote work with the reistry
 $remote_key = "HKLM:\System\CurrentControlSet\Services\Tcpip"
 Invoke-Command -ScriptBlock{Get-ItemProperty -Path $using:remote_key} -ComputerName server1

Update or Add Registry Key Value with PowerShell

Use PowerShell to Enumerate Registry Property Values

Use PowerShell to Edit the Registry on Remote Computers

Use PowerShell to Create New Registry Keys on Remote Systems

Event Logs

 #get-command *event*        
  
 #get-winevent (everything including event channels) vs get-eventlog (legacy log types)
 #get-help get-winevent
 get-winevent
     
 #get a list of the available logs
 get-winevent -listlog *
 Get-WinEvent -listlog *system*
  
 #get particular log
 Get-WinEvent -LogName System
 Get-WinEvent -LogName System -MaxEvents 50
  
 #format the log
 Get-WinEvent -LogName System | select * 
     
 #search for a certain event ID
 get-winevent -logname application | where {$_.id -eq "8196"} 
         
 #limit the amount seen
 get-winevent -logname application -maxevents 1 | where {$_.id -eq "8196"} 
  
 #leverage the filterhashtable for better filtering
 Get-WinEvent -FilterHashtable @{logname='System'; id=7036} -MaxEvents 50
 Get-WinEvent -FilterHashtable @{logname='application'; id=8196; StartTime=(Get-Date).date}
  
 #write event id 7036 to a file
 Get-WinEvent -FilterHashtable @{logname='System'; id=7036} -MaxEvents 50 | select id, providername, timecreated, message | export-csv c:\data\event7036.csv
  
 #copy file locally to review
 copy-item -fromSession $localvm -path c:\data\event7036.csv -Destination c:\data\

Use FilterHashTable to Filter Event Log with PowerShell

Windows Event Log in PowerShell – Part II

Processing Event Logs in PowerShell

Use PowerShell Cmdlet to Filter Event Log for Easy Parsing

Data Mine the Windows Event Log by Using PowerShell and XML

Perfmon or PerfData

 #get-command *counter -module Microsoft.PowerShell.Diagnostics 
 #get-command -Module Microsoft.PowerShell.Diagnostics 
  
 #get-help get-counter
 Get-counter
  
 #Gets list of objects available
 Get-counter –listset *
 #Cleaner list of counters
 Get-Counter -ListSet * | Sort-Object CounterSetName | select CounterSetName 
  
 #Gets list of available counter under a object
 (Get-Counter -ListSet Memory).Paths
  
 #To get information on a single counter
 Get-Counter -Counter "\physicaldisk(_total)\current disk queue length“
  
 #To get 5 collections of a counter
 Get-Counter -Counter "\physicaldisk(_total)\current disk queue length" -MaxSamples 5 
  
 #To get a continuous collection of a counter
 Get-Counter -Continuous -Counter "\physicaldisk(_total)\current disk queue length" 
  
 #Formatted
 Get-counter '\Process(*)\% Processor Time' 
 $p = Get-counter '\Process(*)\% Processor Time‘
 $p.CounterSamples | Sort-Object -Property CookedValue -Descending | Format-Table -Auto
  
 #get counters from remove servers
 $Counter = "\Process(Idle)\% Processor Time"
 Get-Counter -Counter $Counter -ComputerName server1
  
 $DiskReads = "\LogicalDisk(C:)\Disk Reads/sec"
 $DiskReads | Get-Counter -Computer server1,server2 -MaxSamples 10 
  
     
 $_perf_counters = "\Netlogon(_Total)\*","\Security System-Wide Statistics\NTLM Authentications","\Security System-Wide Statistics\Kerberos Authentications","\DirectoryServices(*)\*","\Database(lsass)\*","\NTDS\*","\Memory\*","\PhysicalDisk(*)\*","\Process(*)\*","\Processor(*)\*","\TCPv4\*","\DNS\*"
 $_computers = "server1", "server2", "server3"
 $_counter_results = get-counter -counter $_perf_counters -computer $_computers -ErrorAction SilentlyContinue -maxsamples 10
     
 $_counter_results | export-counter -Path c:\data\perf.blg -FileFormat BLG -force
 $_counter_results | export-counter -Path c:\data\perf.csv -FileFormat csv -force
     
 import-counter -Path c:\data\perf.blg
 import-counter -Path c:\data\perf.blg -Summary
 $blg_counters = import-counter -Path c:\data\perf.blg -ListSet *memory* | ForEach-Object {$_.counter}
 import-counter -Path c:\data\perf.blg -counter $blg_counters 

Using PowerShell To Gather Performance Data

Use PowerShell to Parse Saved Performance Counter Logs

Device and Drivers

 #get-command *pnpdevice*
 Get-pnpdevice
 Get-PnpDevice -PresentOnly | select *
  
 #get-command *driver*
 Get-WindowsDriver -Online -All | select *

PowerTip: Disable plug and play device with PowerShell

PowerTip: Find all devices connected to a computer

Ooooh… PnP Cmdlets & Surface Book Fun!

Network and Network Capture

 #get-command *lbfo*
 #get-help Get-NetLbfoTeam
 #get a list of nic teams
 Get-NetLbfoTeam
 #get-command *net*
 #get-command *netip* -module nettcpip
 #Get ip / set ip
 Get-NetIPAddress
 New-NetIPAddress -InterfaceAlias Ethernet -IPAddress $ipaddress -AddressFamily IPv4 -PrefixLength 24
     
 #get-command *netadapter*
 #get nic
 Get-NetAdapter 
 Get-NetAdapter | select *
 Get-NetAdapter "ethernet 2"
 #disable / enable
 Get-NetAdapter "ethernet 2" | Disable-NetAdapter
 Get-NetAdapter "ethernet 2" | enable-NetAdapter
     
 #get-command *dnsclient*
 #get-command -module dnsclient
 #Get / set dns
 Get-dnsclient
 Get-dnsclientserveraddress
 Set-DnsClientServerAddress -InterfaceAlias Ethernet -ServerAddresses "10.0.0.2"
  
 #similiar to nslookup get ip info from hostname
 Resolve-DnsName -Name server1
 Resolve-DnsName -Name server1 -Type TXT
  
 #get-command *netcon*
 #get-help test-netconnection -example
 #similar to ping
 Test-NetConnection server1
 Test-NetConnection server1 -Port 80
 Test-NetConnection server1 -Port 80 -DiagnoseRouting
 Test-NetConnection server1 -TraceRoute
  
 #Start network strace
 #get-command *neteventsession*
 get-neteventsession
 Remove-NetEventSession
  
 #Get-Command Get-NetTCPConnection
 #get-help  Get-NetTCPConnection
 #view port usauge
 Get-NetTCPConnection 
 Get-NetTCPConnection | group localport -NoElement | sort count -Descending 
 Get-NetTCPConnection | Group-Object -Property State, OwningProcess | Sort Count 
 #add process info
 Get-NetTCPConnection | Group-Object -Property State, OwningProcess | `
     Select -Property Count, Name, @{Name="ProcessName";Expression={(Get-Process -PID ($_.Name.Split(',')[-1].Trim(' '))).Name}} | `
     Sort Count -Descending
  
     
 #get-command *netevent*
 #get-command -module NetEventPacketCapture 
 #set up network trace
 New-NetEventSession -Name "Session2" -LocalFilePath c:\data\capture.etl
 Add-NetEventProvider -Name "Microsoft-Windows-TCPIP" -SessionName "Session2”
 #start trace
 Start-NetEventSession -Name "Session2"
 #stop trace
 Stop-NetEventSession -name "session2"
  
 #use get-winevent to read network trace
 $log = get-winevent -Path C:\data\capture.etl -Oldest
 $log.message 

Windows Server 2012 “Server 8 Beta” NIC teaming

New Networking Diagnostics with PowerShell in Windows Server R2

PowerTip: Use PowerShell to Count Hops to Server

Windows PowerShell equivalents for common networking commands

Packet Sniffing with PowerShell: Getting Started

Use PowerShell to Parse Network Trace Logs

Use PowerShell to Test Connectivity on Remote Servers

Disk

 #get-command *disk*
 #get-command -Module Storage
     
 #get all disk
 get-disk
 get-disk | select *
 Get-PhysicalDisk
 Get-PhysicalDisk | select *
  
 get-Disk | select number, operation*, health*, friendly*, size, @{Name="gb";Expression={$_.size/1GB}}
     
 #prepare and add a new disk
 get-disk 1 | Clear-Disk
 get-disk 1 | initialize-disk  –PartitionStyle MBR
 get-disk 1 | New-Partition -UseMaximumSize -AssignDriveLetter
     
 Get-Disk | Where-Object IsOffline –Eq $True 
     
 #get-command *partition* -module storage
 Get-Partition
  
 #get-command *volume* -module storage
 get-volume
 Get-Volume D | select * 
     
 #move cdrom to another drive letter
 $cddrive = Get-CimInstance win32_volume -Filter 'Driveletter = "D:"'
 $cddrive | Set-CimInstance -Property @{Driveletter="Z:"}
 Get-Volume

Managing Storage with Windows PowerShell on Windows Server 2012

Use PowerShell to Initialize Raw Disks and to Partition and Format Volumes

Patching

 #get-command *hotfix
 #get-help get-hotfix
 get-hotfix
 Get-HotFix  $_.InstalledOn -gt "10/1/2014" -AND $_.InstalledOn -lt "12/11/2014" }
     
 #Get a list of failed updates
 $Failures = Get-ciminstance Win32_ReliabilityRecords
 $Failures | Where { $_.message -match 'failure' } | Select-Object -ExpandProperty message
  
 #retired wuauclt.exe /detectnow
 $AutoUpdates = New-Object -ComObject "Microsoft.Update.AutoUpdate"
 $AutoUpdates.DetectNow()
  
 #Windows update client from repo
 find-module PSWindowsUpdate | install-module
 Import-Module pswindowsupdate
 get-command -Module pswindowsupdate
 new-item -ItemType Directory -Path c:\data\windowsupdate
 #switch to host
 new-item -ItemType Directory -Path c:\data\windowsupdate
 Save-Module -Path c:\data\windowsupdate
 copy-item -FromSession -Path c:\data\windowsupdate\* -Destination c:\data\windowsupdate

Use PowerShell to Find Hotfixes Installed in Time Range

Features Removed or Deprecated in Windows Server 2016

Date, Time, and Time Zone

 #get-command *timezone*
 #get-command *-date*
 get-date
  
 #get timezone information
 Get-TimeZone

 

That is all for now, I hope these blog notes are enjoyed and hopefully found some use out of these cmdlets.

Chad

 

Just a quick note, I use this blog as a way to share things I have discovered. Most of the times I’m in a rush to get it out and my grammar and spelling is horrific. I usually proof read after I post and try to fix things as I see them.