300 likes | 839 Views
Objectives And Takeaways. ObjectivesShow how to use Windows PowerShell 2.0 remoting to manage DesktopsShow how to use Windows PowerShell 2.0 to troubleshoot DesktopsKey TakeawaysWindows PowerShell 2.0 remoting is as easy as typing the name of the computer Interactive sessions allow for more ex
E N D
1. Kyle Rosenthal
Managing Director
Spider Consulting
www.windowspcguy.net
@windowspcguy Using Windows PowerShell for Enterprise Desktop Automation
3. Objectives And Takeaways Objectives
Show how to use Windows PowerShell 2.0 remoting to manage Desktops
Show how to use Windows PowerShell 2.0 to troubleshoot Desktops
Key Takeaways
Windows PowerShell 2.0 remoting is as easy as typing the name of the computer
Interactive sessions allow for more extensive remote scenarios
In this presentation we will talk about using Windows PowerShell 2.0 to manage the remote desktop. We will look at several scenarios: working with processes, services, hotfixes, event logs, hardware inventory, software, and even security. In this presentation we will talk about using Windows PowerShell 2.0 to manage the remote desktop. We will look at several scenarios: working with processes, services, hotfixes, event logs, hardware inventory, software, and even security.
4. What is Windows PowerShell? Console
Interactive commands
Query and configure
Run jobs
Scripting language
Automate everything
Sharable and reusable Windows PowerShell 2.0 comes in two flavors: the command line version, and the script version. You can think of combining the DOS prompt with VBScript. This is something that is foreign to Windows people, but has been around in other computing environments for a long time.
The console gives you the ability to quickly run cmdlets, external executables, and even code in an interactive fashion. In Windows PowerShell 2.0 you can work on the local host, or run commands against remote computers.
Windows PowerShell scripts can use the same cmdlets that are used in the PowerShell console, but can also use COM objects, .NET Framework classes, ADSI, ADO, WMI, and even WIN32 API’s. Windows PowerShell 2.0 comes in two flavors: the command line version, and the script version. You can think of combining the DOS prompt with VBScript. This is something that is foreign to Windows people, but has been around in other computing environments for a long time.
The console gives you the ability to quickly run cmdlets, external executables, and even code in an interactive fashion. In Windows PowerShell 2.0 you can work on the local host, or run commands against remote computers.
Windows PowerShell scripts can use the same cmdlets that are used in the PowerShell console, but can also use COM objects, .NET Framework classes, ADSI, ADO, WMI, and even WIN32 API’s.
5. PowerShell Remoting requirements Not all remoting is the same
Get-Process Get-Service and others use .NET Framework methods
To use Local and remote computer need:
Windows PowerShell 2.0
Microsoft .NET Framework 2.0 or later
Windows Remote Management 2.0
To configure PowerShell remoting:
start PowerShell as admin
Use enable-psremoting cmdlet
Configures firewall and Winrm Service
6. Windows PowerShell Remoting Use the ComputerName parameter with select cmdlets
Get-Process –ComputerName Berlin
Run a command on remote computer
Invoke-Command –ComputerName Berlin ` -ScriptBlock { HostName}
Open a PowerShell session on remote computer
Enter-PSSession –ComputerName Berlin
[berlin]: PS C:\> HostName
[berlin]: PS C:\> Exit-PSSession There are three ways remoting can be accomplished in Windows PowerShell.
The first way to use remoting is to use cmdlets with the –computername parameter. This is also the easiest way to retrieve remote information. As we will see in just a little bit, a large number of cmdlets, such as get-process, allow for the use of the –computername parameter. If you do not want to type get-process, you can use the alias gps and the first letter of the –computername parameter as seen here:
GPS –C Berlin
The second way to use remoting is to use the invoke-command cmdlet to run a command on a remote computer. The command that is run can be either a cmdlet such as Get-ChildItem, or an external executable that is available to the remote computer, such as Hostname.exe. If you do not want to type out Invoke-Command, you can shorten the above command by using the icm alias, and relying upon positional arguments. Written thusly:
Icm berlin {hostname}
The third way to use remoting is to create an interactive remote PowerShell session. To do this, use the Enter-PSSession cmdlet. Once the remote session is established, it changes the PowerShell prompt to include the name of the remote computer in square brackets. As with the Invoke-Command cmdlet, you can shorten the command by using the etsn alias and relying upon positional arguments:
Etsn berlin
Exsn : Alias for Exit-PSSession
There are three ways remoting can be accomplished in Windows PowerShell.
The first way to use remoting is to use cmdlets with the –computername parameter. This is also the easiest way to retrieve remote information. As we will see in just a little bit, a large number of cmdlets, such as get-process, allow for the use of the –computername parameter. If you do not want to type get-process, you can use the alias gps and the first letter of the –computername parameter as seen here:
GPS –C Berlin
The second way to use remoting is to use the invoke-command cmdlet to run a command on a remote computer. The command that is run can be either a cmdlet such as Get-ChildItem, or an external executable that is available to the remote computer, such as Hostname.exe. If you do not want to type out Invoke-Command, you can shorten the above command by using the icm alias, and relying upon positional arguments. Written thusly:
Icm berlin {hostname}
The third way to use remoting is to create an interactive remote PowerShell session. To do this, use the Enter-PSSession cmdlet. Once the remote session is established, it changes the PowerShell prompt to include the name of the remote computer in square brackets. As with the Invoke-Command cmdlet, you can shorten the command by using the etsn alias and relying upon positional arguments:
Etsn berlin
Exsn : Alias for Exit-PSSession
7. 30 ComputerName cmdlets TROUBLESHOOTING
Restart-Computer
Stop-Computer
Test-Connection
Get-Counter
EVENTLOG
Show-EventLog
Write-EventLog
Limit-EventLog
Get-EventLog
Remove-EventLog
New-EventLog
Clear-EventLog
Get-WinEvent As you can see there are a number of cmdlets that support using the –computername parameters.
The above cmdlets are found by this command:
PS C:\> Get-Command -CommandType cmdlet |
Where-Object { $_.definition -match 'computername' } |
Format-Wide -property name –AutoSize
As you can see there are a number of cmdlets that support using the –computername parameters.
The above cmdlets are found by this command:
PS C:\> Get-Command -CommandType cmdlet |
Where-Object { $_.definition -match 'computername' } |
Format-Wide -property name –AutoSize
8. Getting information remotely The same syntax, and experience remotely as locally
Uses credentials of current user
Examples:
Get-Service –computername berlin
Get-Process –computername berlin
Get-HotFix –computername berlin
9 cmdlets
Get-Counter Get-EventLog Get-HotFix
Get-Process Get-Service Get-PSSession
Get-WinEvent Get-WmiObject Get-WSManInstance
Getting access to information is as easy as using get-process, or get-service
PS C:\> Get-Service -Name *server*
PS C:\> Get-Process -Name explorer
PS C:\> Invoke-Command -ComputerName berlin { Stop-Process -Name Notepad }
The above “Get” cmdlets are found by this command:
PS C:\> Get-Command -verb get |
Where-Object { $_.definition -match 'computername' } |
Format-Wide -property name –AutoSize
Getting access to information is as easy as using get-process, or get-service
PS C:\> Get-Service -Name *server*
PS C:\> Get-Process -Name explorer
PS C:\> Invoke-Command -ComputerName berlin { Stop-Process -Name Notepad }
The above “Get” cmdlets are found by this command:
PS C:\> Get-Command -verb get |
Where-Object { $_.definition -match 'computername' } |
Format-Wide -property name –AutoSize
9. Getting information remotely demo Let’s take a look at how easy it is to work with the –comptuername parameter to obtain vital realtime information from our Windows 7 client.
Getting access to information is as easy as using get-process, or get-service.
First we use the cmdlets on the local computer:
PS C:\> Get-Service -Name *server*
PS C:\> Get-Process -Name explorer
NOW we run the commands on a remote computer:
PS C:\> Get-Service -Name *server* -computername Berlin
PS C:\> Get-Process -Name explorer –computername Berlin
Let’s take a look at how easy it is to work with the –comptuername parameter to obtain vital realtime information from our Windows 7 client.
Getting access to information is as easy as using get-process, or get-service.
First we use the cmdlets on the local computer:
PS C:\> Get-Service -Name *server*
PS C:\> Get-Process -Name explorer
NOW we run the commands on a remote computer:
PS C:\> Get-Service -Name *server* -computername Berlin
PS C:\> Get-Process -Name explorer –computername Berlin
10. Working with Services Has a ComputerName Parameter. Use Directly
Get-Service and Set-Service
PS C:\> Get-Service –ComputerName Berlin
No ComputerName parameter. Use Invoke-Command when working remotely
PS C:\> Invoke-Command -ComputerName berlin ` { Start-Service -Name bits }
Start-Service Stop-Service
Restart-Service
Suspend-Service Resume-Service
Before making changes to services
PS C:\> Checkpoint-Computer –Description “Before changed services”
There are 8 cmdlets that are used to work with services.
The Service cmdlets make it really easy to work with services through the service lifecycle: start, stop, restart, resume. You can even create a new service if you wish.
To obtain information on services, you use the Get-Service cmdlet. The Get-Service cmdlet has a number of parameters that provide additional capability
PS C:\> Get-Service -DisplayName server
PS C:\> Get-Service -DependentServices *server*
PS C:\> Get-Service -RequiredServices *server*
PS C:\> Get-Service -RequiredServices lanmanserver
PS C:\> Get-Service -DependentServices lanmanserver
PS C:\> Get-Service -Name *browser* | Format-List -Property *
PS C:\> Get-Service -ComputerName berlin -Name bits
It is the ability to change things that helps to complete the service cycle.
Before making changes to services, use the Checkpoint-Computer cmdlet to create a restore point. DOES NOT WORK ON SERVER VERSIONS OF OS.
PS C:\> Checkpoint-Computer -Description "Before changed services“
You can also specify the type of checkpoint to create:
Valid values restore type values are: APPLICATION_INSTALL, APPLICATION_UNINSTALL, DEVICE_DRIVER_INSTALL, MODIFY_SETTINGS, and CANCELLED_OPERATION.
If you need to restore, you use Restore-Computer cmdlet.
If system restore is disabled, you can use the Enable-ComputerRestore
Using the Set-Service cmdlet we can change things like the description, display name, and start mode. This CAN be done on a local computer, as well as on a remote computer by using –computername parameter.
PS C:\> Set-Service -Name bits -ComputerName berlin -StartupType manual
There is NO –computername switch for Start-Service, Stop-Service, Restart-Service, Suspend-Service, Resume-Service
To work remotely with these, we need to use Invoke-Command. This is shown here:
PS C:\> Invoke-Command -ComputerName berlin { Start-Service -Name bits }
(Get an error if it is disabled.)
PS C:\> Invoke-Command -ComputerName berlin { Start-Service -Name bits }
PS C:\> Invoke-Command -ComputerName berlin { Suspend-Service -Name lanmanserver}
PS C:\> Invoke-Command -ComputerName berlin { Resume-Service -Name lanmanserver}
PS C:\> Get-Service lanmanserver –ComputerName berlinThere are 8 cmdlets that are used to work with services.
The Service cmdlets make it really easy to work with services through the service lifecycle: start, stop, restart, resume. You can even create a new service if you wish.
To obtain information on services, you use the Get-Service cmdlet. The Get-Service cmdlet has a number of parameters that provide additional capability
PS C:\> Get-Service -DisplayName server
PS C:\> Get-Service -DependentServices *server*
PS C:\> Get-Service -RequiredServices *server*
PS C:\> Get-Service -RequiredServices lanmanserver
PS C:\> Get-Service -DependentServices lanmanserver
PS C:\> Get-Service -Name *browser* | Format-List -Property *
PS C:\> Get-Service -ComputerName berlin -Name bits
It is the ability to change things that helps to complete the service cycle.
Before making changes to services, use the Checkpoint-Computer cmdlet to create a restore point. DOES NOT WORK ON SERVER VERSIONS OF OS.
PS C:\> Checkpoint-Computer -Description "Before changed services“
You can also specify the type of checkpoint to create:
Valid values restore type values are: APPLICATION_INSTALL, APPLICATION_UNINSTALL, DEVICE_DRIVER_INSTALL, MODIFY_SETTINGS, and CANCELLED_OPERATION.
If you need to restore, you use Restore-Computer cmdlet.
If system restore is disabled, you can use the Enable-ComputerRestore
Using the Set-Service cmdlet we can change things like the description, display name, and start mode. This CAN be done on a local computer, as well as on a remote computer by using –computername parameter.
PS C:\> Set-Service -Name bits -ComputerName berlin -StartupType manual
There is NO –computername switch for Start-Service, Stop-Service, Restart-Service, Suspend-Service, Resume-Service
To work remotely with these, we need to use Invoke-Command. This is shown here:
PS C:\> Invoke-Command -ComputerName berlin { Start-Service -Name bits }
(Get an error if it is disabled.)
PS C:\> Invoke-Command -ComputerName berlin { Start-Service -Name bits }
PS C:\> Invoke-Command -ComputerName berlin { Suspend-Service -Name lanmanserver}
PS C:\> Invoke-Command -ComputerName berlin { Resume-Service -Name lanmanserver}
PS C:\> Get-Service lanmanserver –ComputerName berlin
11. Working with services remotely demo Let’s take a look at how easy it is to work with the –comptuername parameter to obtain vital realtime information from our Windows 7 client.
PS C:\> Get-Service -DisplayName server
PS C:\> Get-Service -DependentServices *server*
PS C:\> Get-Service -RequiredServices *server*
PS C:\> Get-Service -RequiredServices lanmanserver
PS C:\> Get-Service -DependentServices lanmanserver
PS C:\> Get-Service -Name *browser* | Format-List -Property *
PS C:\> Get-Service -ComputerName berlin -Name bits
PS C:\> Set-Service -Name bits -ComputerName berlin -StartupType manual
There is NO –computername switch for Start-Service, Stop-Service, Restart-Service, Suspend-Service, Resume-Service
To work remotely with these, we need to use Invoke-Command. This is shown here:
PS C:\> Invoke-Command -ComputerName berlin { Start-Service -Name bits }
(Get an error if it is disabled.)
PS C:\> Invoke-Command -ComputerName berlin { Start-Service -Name bits }
PS C:\> Invoke-Command -ComputerName berlin { Suspend-Service -Name lanmanserver}
PS C:\> Invoke-Command -ComputerName berlin { Resume-Service -Name lanmanserver}
PS C:\> Get-Service lanmanserver –ComputerName berlin
Let’s take a look at how easy it is to work with the –comptuername parameter to obtain vital realtime information from our Windows 7 client.
PS C:\> Get-Service -DisplayName server
PS C:\> Get-Service -DependentServices *server*
PS C:\> Get-Service -RequiredServices *server*
PS C:\> Get-Service -RequiredServices lanmanserver
PS C:\> Get-Service -DependentServices lanmanserver
PS C:\> Get-Service -Name *browser* | Format-List -Property *
PS C:\> Get-Service -ComputerName berlin -Name bits
PS C:\> Set-Service -Name bits -ComputerName berlin -StartupType manual
There is NO –computername switch for Start-Service, Stop-Service, Restart-Service, Suspend-Service, Resume-Service
To work remotely with these, we need to use Invoke-Command. This is shown here:
PS C:\> Invoke-Command -ComputerName berlin { Start-Service -Name bits }
(Get an error if it is disabled.)
PS C:\> Invoke-Command -ComputerName berlin { Start-Service -Name bits }
PS C:\> Invoke-Command -ComputerName berlin { Suspend-Service -Name lanmanserver}
PS C:\> Invoke-Command -ComputerName berlin { Resume-Service -Name lanmanserver}
PS C:\> Get-Service lanmanserver –ComputerName berlin
12. Working with Processes There are five process cmdlets
Get-Process Debug-Process Start-Process
Stop-Process Wait-Process
Get-Process. Easy to use remotely and locally
PS C:\> Get-Process –comptuername Berlin –name calc
PS C:\> Get-Process –computername Berlin –id 4072
Start-Process , Stop-Process no computername
PS C:\> Enter-PSSession –comptuername berlin
[berlin]: PS C:\> Start-Process notepad
[berlin]: PS C:\> Get-Process –name notepad
[berlin]: PS C:\> Stop-Process –name notepad
[berlin]: PS C:\> exit
To find *-process cmdlets, use the Get-Command cmdlet as seen here:
PS C:\> Get-Command -Noun process
There are five process cmdlets:
Debug-Process
Get-Process
Start-Process
Stop-Process
Wait-Process
To obtain information about processes:
PS C:\> Get-Process –name notepad
To start a process:
PS C:\> Start-Process notepad
Note: Start-Process does not return anything when it is run. You will need to query or use WMI to capture a Process ID.
To stop a process:
PS C:\> Stop-Process –name notepad
Easy way to work with remote processes:
PS C:\> New-PSSession –Name berlin –ComputerName berlin
PS C:\> Enter-PSSession –comptuername berlin
[berlin]: PS C:\> Start-Process notepad
[berlin]: PS C:\> Get-Process –name notepad
[berlin]: PS C:\> Stop-Process –name notepad
[berlin]: PS C:\> exit
--*** BELOW ILLUSTRATES USING WMI *** DO NOT TALK ABOUT *** Notes only:
Create Remote Process: (Does Not display PID remotely … but creates process)
Use WMI Class accelerator
PS C:\> ([wmiclass]"\\berlin\root\cimv2:win32_process").Create("Notepad.exe")
PS C:\> Get-Process –Name notepad –ComputerName berlin
Capture Return code for process management!
PS C:\> $rtn = ([wmiclass]"\\berlin\root\cimv2:win32_process").Create("Notepad.exe")
PS C:\> $rtn.ProcessId
But this will NOT work (variable is out of scope on remote machine)
PS C:\> invoke-command -computername berlin {Stop-Process -Id $rtn.ProcessId}
You can however, use the local variable, and PASS it when using WMI, as seen here:
Use WMI instance accelerator to use the $rtn.ProcessID
PS C:\> ([wmi]"\\berlin\root\cimv2:win32_process.Handle=$($rtn.ProcessId)").Terminate()
DOES NOT WORK to start a remote process:
PS C:\> invoke-command -ComputerName berlin { Notepad } #note no quotes here
PS C:\> invoke-command -ComputerName berlin { "Notepad.exe" } #quotes here
PS C:\> invoke-command -ComputerName berlin { Start-Process Notepad }
This works locally:
PS C:\> notepad
PS C:\> Stop-Process -Name notepad
There is NO –computername switch for stop-process or Start-ProcessTo find *-process cmdlets, use the Get-Command cmdlet as seen here:
PS C:\> Get-Command -Noun process
There are five process cmdlets:
Debug-Process
Get-Process
Start-Process
Stop-Process
Wait-Process
To obtain information about processes:
PS C:\> Get-Process –name notepad
To start a process:
PS C:\> Start-Process notepad
Note: Start-Process does not return anything when it is run. You will need to query or use WMI to capture a Process ID.
To stop a process:
PS C:\> Stop-Process –name notepad
Easy way to work with remote processes:
PS C:\> New-PSSession –Name berlin –ComputerName berlin
PS C:\> Enter-PSSession –comptuername berlin
[berlin]: PS C:\> Start-Process notepad
[berlin]: PS C:\> Get-Process –name notepad
[berlin]: PS C:\> Stop-Process –name notepad
[berlin]: PS C:\> exit
--*** BELOW ILLUSTRATES USING WMI *** DO NOT TALK ABOUT *** Notes only:
Create Remote Process: (Does Not display PID remotely … but creates process)
Use WMI Class accelerator
PS C:\> ([wmiclass]"\\berlin\root\cimv2:win32_process").Create("Notepad.exe")
PS C:\> Get-Process –Name notepad –ComputerName berlin
Capture Return code for process management!
PS C:\> $rtn = ([wmiclass]"\\berlin\root\cimv2:win32_process").Create("Notepad.exe")
PS C:\> $rtn.ProcessId
But this will NOT work (variable is out of scope on remote machine)
PS C:\> invoke-command -computername berlin {Stop-Process -Id $rtn.ProcessId}
You can however, use the local variable, and PASS it when using WMI, as seen here:
Use WMI instance accelerator to use the $rtn.ProcessID
PS C:\> ([wmi]"\\berlin\root\cimv2:win32_process.Handle=$($rtn.ProcessId)").Terminate()
DOES NOT WORK to start a remote process:
PS C:\> invoke-command -ComputerName berlin { Notepad } #note no quotes here
PS C:\> invoke-command -ComputerName berlin { "Notepad.exe" } #quotes here
PS C:\> invoke-command -ComputerName berlin { Start-Process Notepad }
This works locally:
PS C:\> notepad
PS C:\> Stop-Process -Name notepad
There is NO –computername switch for stop-process or Start-Process
13. Working with Processes demo Let’s demonstrate working with processes. The first thing we need to do is to find all the *-process cmdlets, use the Get-Command cmdlet as seen here:
PS C:\> Get-Command -Noun process
To start a local process:
PS C:\> Start-Process notepad
To obtain information about processes:
PS C:\> Get-Process –name notepad
To stop a process:
PS C:\> Stop-Process –name notepad
Now let’s demonstrate the easy way to work with remote processes:
PS C:\> New-PSSession –Name berlin –ComputerName berlin
PS C:\> Enter-PSSession berlin
[berlin]: PS C:\> Start-Process notepad
[berlin]: PS C:\> Get-Process
[berlin]: PS C:\> Stop-Process –name notepad
[berlin]: PS C:\> exit
---*** BELOW illustrates using WMI *** DO NOT DEMONSTRATE *** notes only --
Create Remote Process: (Does Not display PID remotely … but creates process)
Use WMI Class accelerator
PS C:\> ([wmiclass]"\\berlin\root\cimv2:win32_process").Create("Notepad.exe")
PS C:\> Get-Process –Name notepad –ComputerName berlin
Capture Return code for process management!
PS C:\> $rtn = ([wmiclass]"\\berlin\root\cimv2:win32_process").Create("Notepad.exe")
PS C:\> $rtn.ProcessId
But this will NOT work (variable is out of scope on remote machine)
PS C:\> invoke-command -computername berlin {Stop-Process -Id $rtn.ProcessId}
You can however, use the local variable, and PASS it when using WMI, as seen here:
Use WMI instance accelerator to use the $rtn.ProcessID
PS C:\> ([wmi]"\\berlin\root\cimv2:win32_process.Handle=$($rtn.ProcessId)").Terminate()
DOES NOT WORK to start a remote process:
PS C:\> invoke-command -ComputerName berlin { Notepad } #note no quotes here
PS C:\> invoke-command -ComputerName berlin { "Notepad.exe" } #quotes here
PS C:\> invoke-command -ComputerName berlin { Start-Process Notepad }
This works locally:
PS C:\> notepad
PS C:\> Stop-Process -Name notepad
There is NO –computername switch for stop-process or Start-ProcessLet’s demonstrate working with processes. The first thing we need to do is to find all the *-process cmdlets, use the Get-Command cmdlet as seen here:
PS C:\> Get-Command -Noun process
To start a local process:
PS C:\> Start-Process notepad
To obtain information about processes:
PS C:\> Get-Process –name notepad
To stop a process:
PS C:\> Stop-Process –name notepad
Now let’s demonstrate the easy way to work with remote processes:
PS C:\> New-PSSession –Name berlin –ComputerName berlin
PS C:\> Enter-PSSession berlin
[berlin]: PS C:\> Start-Process notepad
[berlin]: PS C:\> Get-Process
[berlin]: PS C:\> Stop-Process –name notepad
[berlin]: PS C:\> exit
---*** BELOW illustrates using WMI *** DO NOT DEMONSTRATE *** notes only --
Create Remote Process: (Does Not display PID remotely … but creates process)
Use WMI Class accelerator
PS C:\> ([wmiclass]"\\berlin\root\cimv2:win32_process").Create("Notepad.exe")
PS C:\> Get-Process –Name notepad –ComputerName berlin
Capture Return code for process management!
PS C:\> $rtn = ([wmiclass]"\\berlin\root\cimv2:win32_process").Create("Notepad.exe")
PS C:\> $rtn.ProcessId
But this will NOT work (variable is out of scope on remote machine)
PS C:\> invoke-command -computername berlin {Stop-Process -Id $rtn.ProcessId}
You can however, use the local variable, and PASS it when using WMI, as seen here:
Use WMI instance accelerator to use the $rtn.ProcessID
PS C:\> ([wmi]"\\berlin\root\cimv2:win32_process.Handle=$($rtn.ProcessId)").Terminate()
DOES NOT WORK to start a remote process:
PS C:\> invoke-command -ComputerName berlin { Notepad } #note no quotes here
PS C:\> invoke-command -ComputerName berlin { "Notepad.exe" } #quotes here
PS C:\> invoke-command -ComputerName berlin { Start-Process Notepad }
This works locally:
PS C:\> notepad
PS C:\> Stop-Process -Name notepad
There is NO –computername switch for stop-process or Start-Process
14. Working with Hot Fixes Use on Local Computer
PS C:\> Get-HotFix
On remote use computername parameter
PS C:\> Get-HotFix -ComputerName berlin
To search for hot fixes by ID number use id
PS C:\> Get-HotFix -Id KB950099
Search by description to find related hot fixes
PS C:\> Get-HotFix -Description security*
PS C:\> Get-HotFix -Description update
PS C:\> Get-HotFix -Description software*
Check HotFixes:
PS C:\> Get-HotFix -ComputerName berlin
Is it applied to Vista?
PS C:\> Get-HotFix -Id KB950099
Find WHO installed the Hotfix
PS C:\> Get-HotFix | Where-Object { $_.InstalledBy -Match 'nwtraders'}
PS C:\> Get-HotFix | Where-Object { $_.InstalledBy -Match ‘admin'}
Find WHEN HotFixes were installed ## SHOULD WORK >>> CHECK VM Before demo …
PS C:\> $dte = Get-Date 4/1/2008
PS C:\> Get-HotFix | Where-Object { $_.InstalledOn -gt $dte }
Check HotFixes:
PS C:\> Get-HotFix -ComputerName berlin
Is it applied to Vista?
PS C:\> Get-HotFix -Id KB950099
Find WHO installed the Hotfix
PS C:\> Get-HotFix | Where-Object { $_.InstalledBy -Match 'nwtraders'}
PS C:\> Get-HotFix | Where-Object { $_.InstalledBy -Match ‘admin'}
Find WHEN HotFixes were installed ## SHOULD WORK >>> CHECK VM Before demo …
PS C:\> $dte = Get-Date 4/1/2008
PS C:\> Get-HotFix | Where-Object { $_.InstalledOn -gt $dte }
15. Working with Hot fixes demo Let’s take a look at a demonstration that illustrates working with Hotfixes …
First let’s check for hotFixes on a remote computer:
PS C:\> Get-HotFix -ComputerName berlin
Is this hotfix applied to our local computer?
PS C:\> Get-HotFix -Id KB950099
Now let’s see who has been installing the hotfixes on our computer …
Let’s see what hotfixes were installed via domain credentials:
PS C:\> Get-HotFix | Where-Object { $_.InstalledBy -Match 'nwtraders'}
Which hotfixes were installed using admin credentials:
PS C:\> Get-HotFix | Where-Object { $_.InstalledBy -Match ‘admin'}
Find WHEN HotFixes were installed ## SHOULD WORK >>> BUT IS NOT RIGHT NOW!
PS C:\> $dte = Get-Date 4/1/2008
PS C:\> Get-HotFix | Where-Object { $_.InstalledOn -gt $dte }
Let’s take a look at a demonstration that illustrates working with Hotfixes …
First let’s check for hotFixes on a remote computer:
PS C:\> Get-HotFix -ComputerName berlin
Is this hotfix applied to our local computer?
PS C:\> Get-HotFix -Id KB950099
Now let’s see who has been installing the hotfixes on our computer …
Let’s see what hotfixes were installed via domain credentials:
PS C:\> Get-HotFix | Where-Object { $_.InstalledBy -Match 'nwtraders'}
Which hotfixes were installed using admin credentials:
PS C:\> Get-HotFix | Where-Object { $_.InstalledBy -Match ‘admin'}
Find WHEN HotFixes were installed ## SHOULD WORK >>> BUT IS NOT RIGHT NOW!
PS C:\> $dte = Get-Date 4/1/2008
PS C:\> Get-HotFix | Where-Object { $_.InstalledOn -gt $dte }
16. Working with Event logs Two cmdlets. Both support computername
Get-EventLog Get-WinEvent
Get-EventLog
Traditional event logs. Easy to use syntax
PS C:\> Get-EventLog -LogName application ` -ComputerName berlin -Newest 1
Get-WinEvent
Can access diagnostic logs
PS C:\> Get-WinEvent –logname Microsoft-Windows-WinRM/Operational –MaxEvents 1 There are fortunately / unfortunately two cmdlets that work with event logs. The good news, is that with the Get-Winevent cmdlet we can now access the diagnostic logs, and do some really cool stuff … the bad news, is that with two cmdlets… it now gets to be a bit confusing. You can use Get-WinEvent exclusively if you wish.
PS C:\> Get-EventLog –List
PS C:\> Get-EventLog -LogName application -ComputerName berlin -Newest 1
PS C:\> Get-Winevent -ListLog *
PS C:\> Get-Winevent -LogName application -MaxEvents 1
PS C:\> Get-WinEvent –logname Microsoft-Windows-WinRM/Operational –MaxEvents 1There are fortunately / unfortunately two cmdlets that work with event logs. The good news, is that with the Get-Winevent cmdlet we can now access the diagnostic logs, and do some really cool stuff … the bad news, is that with two cmdlets… it now gets to be a bit confusing. You can use Get-WinEvent exclusively if you wish.
PS C:\> Get-EventLog –List
PS C:\> Get-EventLog -LogName application -ComputerName berlin -Newest 1
PS C:\> Get-Winevent -ListLog *
PS C:\> Get-Winevent -LogName application -MaxEvents 1
PS C:\> Get-WinEvent –logname Microsoft-Windows-WinRM/Operational –MaxEvents 1
17. Using Get-EventLog Use to access classic event logs only
Use LogName parameter to specify log
System, Application, Security etc.
PS C:\> Get-EventLog –LogName Application
Use Source parameter filters where event from
PS C:\> Get-EventLog -LogName application -Source vss
Use Newest parameter to limit number records
Use EntryType parameter to limit type records
Error, Warning, Information, Auditing
Use ComputerName parameter to remote
PS C:\> Get-EventLog -LogName application -Source vss -Newest 10
PS C:\> Get-EventLog -LogName application -Newest 10 -EntryType Warning
PS C:\> $start = Get-Date 1/5/2009
PS C:\> $done = Get-Date 1/8/2009
PS C:\> Get-EventLog -LogName application -After $start -Before $done –source vss
PS C:\> Get-EventLog -LogName application -Source vss -Newest 10
PS C:\> Get-EventLog -LogName application -Newest 10 -EntryType Warning
PS C:\> $start = Get-Date 1/5/2009
PS C:\> $done = Get-Date 1/8/2009
PS C:\> Get-EventLog -LogName application -After $start -Before $done –source vss
18. Using Get-WinEvent Use the ListLog parameter to list logs
Use wild cards to search for logs *winrm*
Use LogName parameter to query logs
Use wild cards for log name as well *winrm*
Use when have single match, only one with events
Use ListProvider parameter to display sources
To use the ETW diagnostic logs
Enable ETW diagnostic logging
ETW logs can only be played Forward. An error is returned unless you use –oldest switch
More information in Advanced Scripting Talk by Dan Harmon
When accessing the new management logs, keep in mind that what you see in the Event Viewer tool is not the name needed to access the log. In the log view you will see a log name .. This is NOT the name of the log needed. You need to switch to XML view of the details. There you will see the provider.
Wild cards can be used :
PS C:\> Get-WinEvent -ListLog *winrm* | Format-List -Property *
PS C:\> Get-WinEvent -LogName *winrm* -MaxEvents 1
Can use wild card that returns multiple logs if only one has events
PS C:\> Get-WinEvent -ListLog *remote*
PS C:\> Get-WinEvent -LogName *remote* -MaxEvents 1
To enable diagnostic ETW trace logs:
Open EventViewer
Select View and click Show Analytic Debug Logs
Navigate to Applications and Services logs -> Microsoft ->Windows -> WMI-Activity for example
Right click on the Trace log and select Enable Log
When done with repro Right click trace log select Disable Log
List WMI Providers
PS C:\> Get-WinEvent -ListProvider *wmi*
PS C:\> Get-WinEvent -ListProvider *wmi* | Format-List -Property *
NOW LET’S Generate some WMI Activity!
PowerShell C:\> Gwmi WIN32_bios
NOW WE will have to wait a few seconds for the logging to take place …
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" –Oldest
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" -Oldest |
Where-Object { $_.id -eq 1}
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" -Oldest |
Where-Object { $_.id -eq 1 -AND $_.Message -match 'Win32_BIOS'} |
format-List -Property *
When accessing the new management logs, keep in mind that what you see in the Event Viewer tool is not the name needed to access the log. In the log view you will see a log name .. This is NOT the name of the log needed. You need to switch to XML view of the details. There you will see the provider.
Wild cards can be used :
PS C:\> Get-WinEvent -ListLog *winrm* | Format-List -Property *
PS C:\> Get-WinEvent -LogName *winrm* -MaxEvents 1
Can use wild card that returns multiple logs if only one has events
PS C:\> Get-WinEvent -ListLog *remote*
PS C:\> Get-WinEvent -LogName *remote* -MaxEvents 1
To enable diagnostic ETW trace logs:
Open EventViewer
Select View and click Show Analytic Debug Logs
Navigate to Applications and Services logs -> Microsoft ->Windows -> WMI-Activity for example
Right click on the Trace log and select Enable Log
When done with repro Right click trace log select Disable Log
List WMI Providers
PS C:\> Get-WinEvent -ListProvider *wmi*
PS C:\> Get-WinEvent -ListProvider *wmi* | Format-List -Property *
NOW LET’S Generate some WMI Activity!
PowerShell C:\> Gwmi WIN32_bios
NOW WE will have to wait a few seconds for the logging to take place …
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" –Oldest
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" -Oldest |
Where-Object { $_.id -eq 1}
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" -Oldest |
Where-Object { $_.id -eq 1 -AND $_.Message -match 'Win32_BIOS'} |
format-List -Property *
19. Working with Event logs demo Let’s now demonstrate working with Event logs using Windows PowerShell:
First let’s see what the most recent event in the application log is:
PS C:\> Get-EventLog -LogName application -Newest 1
Now let’s look at events from vss
PS C:\> Get-EventLog -LogName application -Source vss -Newest 10
Or how about the 10 most recent errors
PS C:\> Get-EventLog -LogName application -Newest 10 -EntryType Warning
Now let’s do something a bit more tricky. Let’s look for event log entries that occurred during a 3 day period:
PS C:\> $after = Get-Date 5/9/2009
PS C:\> $before = Get-Date 5/14/2009
PS C:\> Get-EventLog -LogName application -After $after -Before $before –EntryType warning
NOW LET’S TRY THE GET-WINEVENT cmdlet.
We can use the Get-WinEvent cmdlet to access the traditional event logs:
PS C:\> Get-WinEvent -LogName application -MaxEvents 1
But the real power comes in being able to work with the new management logs:
When accessing the new management logs, keep in mind that what you see in the Event Viewer tool is not the name needed to access the log. In the log view you will see a log name .. This is NOT the name of the log needed. You need to switch to XML view of the details. There you will see the provider.
Wild cards can be used :
PS C:\> Get-WinEvent -ListLog *winrm* | Format-List -Property *
PS C:\> Get-WinEvent -LogName *winrm* -MaxEvents 1
Can use wild card that returns multiple logs if only one has events
PS C:\> Get-WinEvent -ListLog *remote*
PS C:\> Get-WinEvent -LogName *remote* -MaxEvents 1
NOW let’s look at working with a trace log:
To enable diagnostic ETW trace logs:
Open EventViewer
Select View and click Show Analytic Debug Logs
Navigate to Applications and Services logs -> Microsoft ->Windows -> WMI-Activity for example
Click the + beside WMI-Activity to open up the logs
Right click on the Trace log and select Enable Log
When done with repro Right click trace log select Disable Log
List WMI Providers
PS C:\> Get-WinEvent -ListProvider *wmi*
PS C:\> Get-WinEvent -ListProvider *wmi* | Format-List -Property *
NOW LET’S Generate some WMI Activity!
PowerShell C:\> Gwmi WIN32_bios
NOW WE will have to wait a few seconds for the logging to take place …
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" –Oldest
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" -Oldest |
Where-Object { $_.id -eq 1}
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" -Oldest |
Where-Object { $_.id -eq 1 -AND $_.Message -match 'Win32_BIOS'} |
format-List -Property *
Let’s now demonstrate working with Event logs using Windows PowerShell:
First let’s see what the most recent event in the application log is:
PS C:\> Get-EventLog -LogName application -Newest 1
Now let’s look at events from vss
PS C:\> Get-EventLog -LogName application -Source vss -Newest 10
Or how about the 10 most recent errors
PS C:\> Get-EventLog -LogName application -Newest 10 -EntryType Warning
Now let’s do something a bit more tricky. Let’s look for event log entries that occurred during a 3 day period:
PS C:\> $after = Get-Date 5/9/2009
PS C:\> $before = Get-Date 5/14/2009
PS C:\> Get-EventLog -LogName application -After $after -Before $before –EntryType warning
NOW LET’S TRY THE GET-WINEVENT cmdlet.
We can use the Get-WinEvent cmdlet to access the traditional event logs:
PS C:\> Get-WinEvent -LogName application -MaxEvents 1
But the real power comes in being able to work with the new management logs:
When accessing the new management logs, keep in mind that what you see in the Event Viewer tool is not the name needed to access the log. In the log view you will see a log name .. This is NOT the name of the log needed. You need to switch to XML view of the details. There you will see the provider.
Wild cards can be used :
PS C:\> Get-WinEvent -ListLog *winrm* | Format-List -Property *
PS C:\> Get-WinEvent -LogName *winrm* -MaxEvents 1
Can use wild card that returns multiple logs if only one has events
PS C:\> Get-WinEvent -ListLog *remote*
PS C:\> Get-WinEvent -LogName *remote* -MaxEvents 1
NOW let’s look at working with a trace log:
To enable diagnostic ETW trace logs:
Open EventViewer
Select View and click Show Analytic Debug Logs
Navigate to Applications and Services logs -> Microsoft ->Windows -> WMI-Activity for example
Click the + beside WMI-Activity to open up the logs
Right click on the Trace log and select Enable Log
When done with repro Right click trace log select Disable Log
List WMI Providers
PS C:\> Get-WinEvent -ListProvider *wmi*
PS C:\> Get-WinEvent -ListProvider *wmi* | Format-List -Property *
NOW LET’S Generate some WMI Activity!
PowerShell C:\> Gwmi WIN32_bios
NOW WE will have to wait a few seconds for the logging to take place …
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" –Oldest
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" -Oldest |
Where-Object { $_.id -eq 1}
PS C:\> Get-WinEvent -LogName "Microsoft-Windows-WMI-Activity/Trace" -Oldest |
Where-Object { $_.id -eq 1 -AND $_.Message -match 'Win32_BIOS'} |
format-List -Property *
20. Using WMI Events Do not confuse with event logs.
Easy to work with temporary short term events
Monitor for process creation
Monitor for service stopping
Monitor for USB drive attached to system
Use Register-WmiEvent to create
Uses intrinsic WMI event classes, or generics
Can be local or remote. Remote credentials if need
Retrieve by Get-Event and SourceIdentifier
UnRegister-Event or Remove-Event when done
The ability to work with WMI eventing is a real win for network administrators. There is always a lot of interest in WMI events, but until now this has always been a very specialized area. The VBScripts that do WMI eventing are rather complicated, and when they work it is often as suprising for the writer of the script as for the person who needs the script. Keep in mind this is not a substitute for Systems Center Operations Manager. These are short term events.
Intrinsic WMI event classes are easy:
PS C:\> Register-WmiEvent -Class Win32_ProcessStartTrace -SourceIdentifier MyEvent
PS C:\> Notepad
BELOW Event Source was case sensitive in earler builds. But has now been fixed.
PS C:\> Get-Event -SourceIdentifier MyEvent
PS C:\> Unregister-Event -SourceIdentifier MyEvent
PS C:\> Remove-Event -SourceIdentifier MyEvent
To use generic WMI event classes, you must create a query. This would allow you to easily copy old vbscripts:
PS C:\> Register-WmiEvent -query "Select * from __InstanceCreationEvent within 5
where targetinstance isa 'win32_process'" -SourceIdentifier myevent
PS C:\> notepad
PS C:\> Get-Event
The ability to work with WMI eventing is a real win for network administrators. There is always a lot of interest in WMI events, but until now this has always been a very specialized area. The VBScripts that do WMI eventing are rather complicated, and when they work it is often as suprising for the writer of the script as for the person who needs the script. Keep in mind this is not a substitute for Systems Center Operations Manager. These are short term events.
Intrinsic WMI event classes are easy:
PS C:\> Register-WmiEvent -Class Win32_ProcessStartTrace -SourceIdentifier MyEvent
PS C:\> Notepad
BELOW Event Source was case sensitive in earler builds. But has now been fixed.
PS C:\> Get-Event -SourceIdentifier MyEvent
PS C:\> Unregister-Event -SourceIdentifier MyEvent
PS C:\> Remove-Event -SourceIdentifier MyEvent
To use generic WMI event classes, you must create a query. This would allow you to easily copy old vbscripts:
PS C:\> Register-WmiEvent -query "Select * from __InstanceCreationEvent within 5
where targetinstance isa 'win32_process'" -SourceIdentifier myevent
PS C:\> notepad
PS C:\> Get-Event
21. Working with WMI Events demo PS C:\> Register-WmiEvent -Class Win32_ProcessStartTrace -SourceIdentifier MyEvent
PS C:\> Notepad
BELOW Event Source is Case Sensitive!!!!!
PS C:\> Get-Event -SourceIdentifier MyEvent
PS C:\> Unregister-Event -SourceIdentifier MyEvent
PS C:\> Remove-Event -SourceIdentifier MyEvent
Here is an example of using a generic WMI event class (use the RegisterWmi.ps1 script)**
PS C:\> Register-WmiEvent -query "Select * from __InstanceCreationEvent within 5
where targetinstance isa 'win32_process'" -SourceIdentifier myevent
PS C:\> notepad
PS C:\> Get-Event
PS C:\> Remove-Event -SourceIdentifier myevent
PS C:\> Register-WmiEvent -Class Win32_ProcessStartTrace -SourceIdentifier MyEvent
PS C:\> Notepad
BELOW Event Source is Case Sensitive!!!!!
PS C:\> Get-Event -SourceIdentifier MyEvent
PS C:\> Unregister-Event -SourceIdentifier MyEvent
PS C:\> Remove-Event -SourceIdentifier MyEvent
Here is an example of using a generic WMI event class (use the RegisterWmi.ps1 script)**
PS C:\> Register-WmiEvent -query "Select * from __InstanceCreationEvent within 5
where targetinstance isa 'win32_process'" -SourceIdentifier myevent
PS C:\> notepad
PS C:\> Get-Event
PS C:\> Remove-Event -SourceIdentifier myevent
22. Working with Hardware Inventory Use the Get-WmiObject cmdlet to work with WMI
Basic query uses Class and Computername
PS C:\> Get-WmiObject -Class Win32_Bios ` -ComputerName berlin
PS C:\> gwmi win32_Bios -co berlin
Use Credential parameter for remote if need
Other parameters allow full WMI
Amended Authentication Authority
Impersonation EnableAllPrivileges
Get-Help Get-WmiObject –Detailed
-amended use amended qualifiers … can be localized information
-authentication PacketPrivacy is 6 (encrypted)
-authority NTLM, Kerberos etc
-enableAllPrivileges enables all privileges … not surprising here… In VBScript days had to know if needed shutdown, loaddriver, debug, or any of 24 other privileges that were required to perform certain operations. Now just enable all privileges.
One class on two computers:
PS C:\> Get-WmiObject -class win32_bios -computername vista,berlin
OR the Longer Way:
PS C:\> "Berlin","Vista" |
ForEach-Object -begin { "Obtaining Bios information:"
} -Process { "$_ bios information:" ;
Get-WmiObject -Class Win32_Bios -ComputerName $_ }
One computer, multiple classes:
PS C:\> "Win32_Processor","Win32_Volume","Win32_ComputerSystem", "Win32_VideoController" |
ForEach-Object { Get-WmiObject -Class $_ } >> C:\Fso\MyComputerInfo.txt ;
Notepad c:\fso\MyComputerInfo.txt
Access Windows Performance metric
Get-WmiObject –Class Win32_WinSatGet-Help Get-WmiObject –Detailed
-amended use amended qualifiers … can be localized information
-authentication PacketPrivacy is 6 (encrypted)
-authority NTLM, Kerberos etc
-enableAllPrivileges enables all privileges … not surprising here… In VBScript days had to know if needed shutdown, loaddriver, debug, or any of 24 other privileges that were required to perform certain operations. Now just enable all privileges.
One class on two computers:
PS C:\> Get-WmiObject -class win32_bios -computername vista,berlin
OR the Longer Way:
PS C:\> "Berlin","Vista" |
ForEach-Object -begin { "Obtaining Bios information:"
} -Process { "$_ bios information:" ;
Get-WmiObject -Class Win32_Bios -ComputerName $_ }
One computer, multiple classes:
PS C:\> "Win32_Processor","Win32_Volume","Win32_ComputerSystem", "Win32_VideoController" |
ForEach-Object { Get-WmiObject -Class $_ } >> C:\Fso\MyComputerInfo.txt ;
Notepad c:\fso\MyComputerInfo.txt
Access Windows Performance metric
Get-WmiObject –Class Win32_WinSat
23. Working with hardware inventory demo Now let’s demonstrate working with hardware inventory by using WMI.
The Get-WmiObject cmdlet has a number of very useful parameters…a number of which have been added for PowerShell 2.0. The syntax, however, has been kept rather simple. The trick is to remember which parameters are available. Use Get-Help:
Get-Help Get-WmiObject –Detailed | more
-amended use amended qualifiers … can be localized information
-authentication PacketPrivacy is 6 (encrypted)
-authority NTLM, Kerberos etc
-enableAllPrivileges enables all privileges … not surprising here…
Get volume information:
PS C:\> Get-WmiObject -Class win32_volume
Get computer summary information:
PS C:\> Get-WmiObject -Class win32_computersystem
Get computer processor information:
PS C:\> Get-WmiObject -Class win32_processor
Access Windows Performance metric
Get-WmiObject –Class Win32_WinSat
When have a command that will take some time, use the –asjob parameter
Get-wmiobject –class WIN32_service –computer berlin -asjob
One class on two computers:
PS C:\> Get-WmiObject -class win32_bios -computername win7,berlin
Now let’s check our job:
Receive-Job –name job1
*** DO NOT DEMO ***
OR the Longer Way:
PS C:\> "Berlin",“win7" |
ForEach-Object -begin { "Obtaining Bios information:"
} -Process { "$_ bios information:" ;
Get-WmiObject -Class Win32_Bios -ComputerName $_ }
One computer, multiple classes:
PS C:\> "Win32_Processor","Win32_Volume","Win32_ComputerSystem", "Win32_VideoController" |
ForEach-Object { Get-WmiObject -Class $_ } >> C:\Fso\MyComputerInfo.txt ;
Notepad c:\fso\MyComputerInfo.txt
Access Windows Performance metric
Get-WmiObject –Class Win32_WinSatNow let’s demonstrate working with hardware inventory by using WMI.
The Get-WmiObject cmdlet has a number of very useful parameters…a number of which have been added for PowerShell 2.0. The syntax, however, has been kept rather simple. The trick is to remember which parameters are available. Use Get-Help:
Get-Help Get-WmiObject –Detailed | more
-amended use amended qualifiers … can be localized information
-authentication PacketPrivacy is 6 (encrypted)
-authority NTLM, Kerberos etc
-enableAllPrivileges enables all privileges … not surprising here…
Get volume information:
PS C:\> Get-WmiObject -Class win32_volume
Get computer summary information:
PS C:\> Get-WmiObject -Class win32_computersystem
Get computer processor information:
PS C:\> Get-WmiObject -Class win32_processor
Access Windows Performance metric
Get-WmiObject –Class Win32_WinSat
When have a command that will take some time, use the –asjob parameter
Get-wmiobject –class WIN32_service –computer berlin -asjob
One class on two computers:
PS C:\> Get-WmiObject -class win32_bios -computername win7,berlin
Now let’s check our job:
Receive-Job –name job1
*** DO NOT DEMO ***
OR the Longer Way:
PS C:\> "Berlin",“win7" |
ForEach-Object -begin { "Obtaining Bios information:"
} -Process { "$_ bios information:" ;
Get-WmiObject -Class Win32_Bios -ComputerName $_ }
One computer, multiple classes:
PS C:\> "Win32_Processor","Win32_Volume","Win32_ComputerSystem", "Win32_VideoController" |
ForEach-Object { Get-WmiObject -Class $_ } >> C:\Fso\MyComputerInfo.txt ;
Notepad c:\fso\MyComputerInfo.txt
Access Windows Performance metric
Get-WmiObject –Class Win32_WinSat
24. Working with Software Uses Win32_Product WMI class
Uses MSIPROV
Installed by default on:
Windows 7
Windows Server 2008 R2
Windows Server 2008
Windows Vista, and Windows XP
Need to Add on Windows Server 2003
Use to inventory software installed via MSI
Install Method to install software
Uninstall Method to uninstall software
Following code installs hello world from network share … then it will uninstall it
$servers = “Berlin",“Vista"
foreach($server in $servers)
{
([wmiclass]"\\$server\root\cimv2:win32_product").install("\\Berlin\students\helloworld.msi")
}
$classKey = "IdentifyingNumber=`"`{9B37B393-35D6-4663-B19F-3C1BA8518815`}`",Name=`"HelloWorld`",Version=`"1.0.0`"“
foreach($server in $servers)
{
([wmi]"\\$server\root\cimv2:Win32_Product.$classKey").uninstall()
}Following code installs hello world from network share … then it will uninstall it
$servers = “Berlin",“Vista"
foreach($server in $servers)
{
([wmiclass]"\\$server\root\cimv2:win32_product").install("\\Berlin\students\helloworld.msi")
}
$classKey = "IdentifyingNumber=`"`{9B37B393-35D6-4663-B19F-3C1BA8518815`}`",Name=`"HelloWorld`",Version=`"1.0.0`"“
foreach($server in $servers)
{
([wmi]"\\$server\root\cimv2:Win32_Product.$classKey").uninstall()
}
25. Working with software demo Following code installs hello world from network share … then it will uninstall it. I am not going to type this code in, we will use the new PowerShell ISE (Integrated Scripting Environment) and look at a script we have already written:
$servers = “Berlin",“Vista"
foreach($server in $servers)
{
([wmiclass]"\\$server\root\cimv2:win32_product").install("\\Berlin\students\helloworld.msi")
}
$classKey = "IdentifyingNumber=`"`{9B37B393-35D6-4663-B19F-3C1BA8518815`}`",Name=`"HelloWorld`",Version=`"1.0.0`"“
foreach($server in $servers)
{
([wmi]"\\$server\root\cimv2:Win32_Product.$classKey").uninstall()
}
Following code installs hello world from network share … then it will uninstall it. I am not going to type this code in, we will use the new PowerShell ISE (Integrated Scripting Environment) and look at a script we have already written:
$servers = “Berlin",“Vista"
foreach($server in $servers)
{
([wmiclass]"\\$server\root\cimv2:win32_product").install("\\Berlin\students\helloworld.msi")
}
$classKey = "IdentifyingNumber=`"`{9B37B393-35D6-4663-B19F-3C1BA8518815`}`",Name=`"HelloWorld`",Version=`"1.0.0`"“
foreach($server in $servers)
{
([wmi]"\\$server\root\cimv2:Win32_Product.$classKey").uninstall()
}
26. Setting security Best to use ICACLS.exe
Installed on –Windows Vista and above
Available on Windows Server 2003 SP2
You need the hotfix 943043 to fix inheritance issue
PS C:\> icacls test /Deny Everyone:`(R`)
PS C:\> icacls test /Grant Everyone:`(F`)
Get-ACL
Retrieves the security descriptor from item
Set-ACL
Sets the security descriptor on item http://www.microsoft.com/downloads/details.aspx?FamilyID=E8BA3E56-D8FE-4A91-93CF-ED6985E3927B&displaylang=en
http://support.microsoft.com/kb/919240
http://support.microsoft.com/kb/943043
NOTE: You will need to escape ` the parenthesis in the icacls command
PowerShell C:\> dir # to see if Test directory exists … if it does not then create it.
PS C:\> New-Item -Path c:\test -ItemType directory
PS C:\> icacls test /Deny Everyone:`(R`)
PS C:\> icacls test /Grant Everyone:`(F`)
You can also do this remotely:
PS C:\> Enter-PSSession -ComputerName berlin
[berlin]: PS C:\> New-Item -Path c:\test -ItemType directory
[berlin]: PS C:\> icacls test /deny Everyone:`(R`)
Over on Berlin you will see you no longer have permission to the folder. Back on Vista, we can type this command
[berlin]: PS C:\> icacls test /Grant Everyone:`(F`)
Now on Berlin you will see you do have permission. Back to Vista, we exit the session.
[berlin]: PS C:\> Exit-PSSession
PS C:\> "test","test1" |
Foreach-object {New-Item -Path c:\ -Name $_ -ItemType directory}
Now open test and change the security via explorer
PS C:\> get-acl -Path C:\test | Set-Acl -Path C:\test1
Now Open and inspect security on Test1 via explorer
PS C:\> (get-acl C:\test).AccessTOSTring
PS C:\> Get-Acl -Path 'HKCU:\Volatile Environment' | Format-List *
XP tools:
Cacls.exe
SubInAcl.exe (download)
http://www.microsoft.com/downloads/details.aspx?FamilyID=E8BA3E56-D8FE-4A91-93CF-ED6985E3927B&displaylang=en
http://support.microsoft.com/kb/919240
http://support.microsoft.com/kb/943043
NOTE: You will need to escape ` the parenthesis in the icacls command
PowerShell C:\> dir # to see if Test directory exists … if it does not then create it.
PS C:\> New-Item -Path c:\test -ItemType directory
PS C:\> icacls test /Deny Everyone:`(R`)
PS C:\> icacls test /Grant Everyone:`(F`)
You can also do this remotely:
PS C:\> Enter-PSSession -ComputerName berlin
[berlin]: PS C:\> New-Item -Path c:\test -ItemType directory
[berlin]: PS C:\> icacls test /deny Everyone:`(R`)
Over on Berlin you will see you no longer have permission to the folder. Back on Vista, we can type this command
[berlin]: PS C:\> icacls test /Grant Everyone:`(F`)
Now on Berlin you will see you do have permission. Back to Vista, we exit the session.
[berlin]: PS C:\> Exit-PSSession
PS C:\> "test","test1" |
Foreach-object {New-Item -Path c:\ -Name $_ -ItemType directory}
Now open test and change the security via explorer
PS C:\> get-acl -Path C:\test | Set-Acl -Path C:\test1
Now Open and inspect security on Test1 via explorer
PS C:\> (get-acl C:\test).AccessTOSTring
PS C:\> Get-Acl -Path 'HKCU:\Volatile Environment' | Format-List *
XP tools:
Cacls.exe
SubInAcl.exe (download)
27. Setting Security demo Let’s now demonstrate working with security:
NOTE: You will need to escape ` the parenthesis in the icacls command
PowerShell C:\> dir # to see if Test directory exists … if it does not then create it.
PS C:\> New-Item -Path c:\test -ItemType directory
PS C:\> icacls test /Deny Everyone:`(R`)
PS C:\> icacls test /Grant Everyone:`(F`)
You can also do this remotely:
PS C:\> Enter-PSSession -ComputerName berlin
[berlin]: PS C:\> New-Item -Path c:\test -ItemType directory
[berlin]: PS C:\> icacls test /deny Everyone:`(R`)
Over on Berlin you will see you no longer have permission to the folder. Back on Vista, we can type this command
[berlin]: PS C:\> icacls test /Grant Everyone:`(F`)
Now on Berlin you will see you do have permission. Back to Vista, we exit the session.
[berlin]: PS C:\> Exit-PSSession
PS C:\> "test","test1" |
Foreach-object {New-Item -Path c:\ -Name $_ -ItemType directory}
Now open test and change the security via explorer
PS C:\> get-acl -Path C:\test | Set-Acl -Path C:\test1
Now Open and inspect security on Test1 via explorer
PS C:\> (get-acl C:\test).AccessTOSTring
PS C:\> Get-Acl -Path 'HKCU:\Volatile Environment' | Format-List *
Let’s now demonstrate working with security:
NOTE: You will need to escape ` the parenthesis in the icacls command
PowerShell C:\> dir # to see if Test directory exists … if it does not then create it.
PS C:\> New-Item -Path c:\test -ItemType directory
PS C:\> icacls test /Deny Everyone:`(R`)
PS C:\> icacls test /Grant Everyone:`(F`)
You can also do this remotely:
PS C:\> Enter-PSSession -ComputerName berlin
[berlin]: PS C:\> New-Item -Path c:\test -ItemType directory
[berlin]: PS C:\> icacls test /deny Everyone:`(R`)
Over on Berlin you will see you no longer have permission to the folder. Back on Vista, we can type this command
[berlin]: PS C:\> icacls test /Grant Everyone:`(F`)
Now on Berlin you will see you do have permission. Back to Vista, we exit the session.
[berlin]: PS C:\> Exit-PSSession
PS C:\> "test","test1" |
Foreach-object {New-Item -Path c:\ -Name $_ -ItemType directory}
Now open test and change the security via explorer
PS C:\> get-acl -Path C:\test | Set-Acl -Path C:\test1
Now Open and inspect security on Test1 via explorer
PS C:\> (get-acl C:\test).AccessTOSTring
PS C:\> Get-Acl -Path 'HKCU:\Volatile Environment' | Format-List *
28. Question & Answer Session
29. Related Content SVR301 Administrator's Idol: Windows and Active Directory Best Practices SVR304 Windows Server 2008 R2: Tips on Automating and Managing the Breadth of Your IT Environment THBTU03 Everything you need to learn Windows PowerShell SVR308 Managing Windows Server Core
31. Resources