• Aucun résultat trouvé

Detecting Changes to Objects

Dans le document Copyright Copyright (Page 140-143)

If you use Compare-Object as described above, it will only check whether every object in one list is matched in another list. While comparing them to their initial state, may be sufficient to determine whether objects were removed or added, you can't use this approach to establish whether an object's inner status has changed.

For example, if you'd like to verify whether services have stopped or started in comparison to their defined initial state, Compare-Object won't initially help you because when a service is stopped it still exists: only its inner status has changed. You should instead instruct Compare-Object to compare one or more of the object's properties by using Format-List to easily determine which properties are available to you. You should. first acquire a service object and experiment around with it a little:

# Pick out Windows Update Service:

$service = Get-Service wuauserv

# Inspect all properties of this services:

$service | Format-List *

Name : wuauserv CanPauseAndContinue : False CanShutdown : True CanStop : True

DisplayName : Windows Update DependentServices : {}

MachineName : .

ServiceName : wuauserv ServicesDependedOn : {rpcss}

ServiceHandle :

Status : Running

ServiceType : Win32ShareProcess Site :

Container :

It quickly turns out that the Status property retrieves the desired information. So, you could first make another snapshot of all services, stop a service subsequently, and then instruct Compare-Object to use the Status property to ascertain differences:

# Save current state:

$before = Get-Service

# Pick out a service and stop this service:

# (Note: this usually requires administrator rights.

# Stop services only if you are sure that the service

# is absolutely not required.

$service = Get-Service wuauserv

$service.Stop()

# Record after state:

$after = Get-Service

# A simple comparison will not find differences because

# the service existed before and after:

Compare-Object $before $after

# A comparison of the Status property reports the halted

# service but not its name:

Compare-Object $before $after -Property Status Status SideIndicator

--- ---Stopped =>

Running <=

# A comparison with the Status and Name properties returns

# the required information:

Compare-Object $before $after -Property Status, Name

Status Name SideIndicator --- ---- ---Stopped wuauserv =>

Running wuauserv <=

If you instruct Compare-Object with the parameter -property to compare the Status and Name properties, you'll receive the information you want: the service wuauserv was executed in the list in

$before, but not in the list in $after. So it was stopped.

This example shows how to stop services. In the next chapter, you'll learn more about the methods (commands) built into objects.

What's important to note here is only that you change the state of any service. You could also accomplish that by using the Microsoft Management Console Snapin for services:

services.msc

Start or stop only those services that you know won't incur any risk when you start or stop them. If an error message pops up when you try to modify a service, this is usually because you don't have administrator rights. Just

remember that for Vista, or when group policies are in effect, that you must start up PowerShell with administrator rights. Otherwise, you're only a normal user, even if you log on with an administrator account.

Since the Compare-Object results consist of objects, you could make a further analysis of the result.

Perhaps all that interests you are executed modifications. Use a pipeline filter, such as Where-Object, to specify to the filter that you're interested in only those objects in which the SideIndicator property corresponds to the value "=":

Compare-Object $before $after -property Status, Name |

Where-Object { $_.SideIndicator -eq "=>" } Status Name SideIndicator

--- ---- ---Stopped wuauserv =>

If you'd like to formulate the result in plain text, use a loop, such as, Where-Object, and use the information in the retrieved objects to put together the plain text:

Compare-Object $before $after -property Status, Name | Where-Object { $_.SideIndicator -eq "=>" } |

ForEach-Object { "The service {0} has changed its status to {1}" ` -f $_.Name, $_.Status}

The service wuauserv has changed its status to Stopped

You can use this same procedure for widely varying monitoring tasks. Think in advance about which command you could use to determine an object's status to be monitored and, which of the object's properties will describe its status. For example, if you want to find out whether files in a directory have changed, the right command would be Dir and the property could be Length (because of the changed file size) or LastWriteTime (the contents could have been changed even if its size is just as large as it was before). Here's an example:

# Create test file and Before snapshot of the directory:

"Hello" > test.txt

$before = Dir

# Modify test file and create After snapshot of the directory:

"Hello world" > test.txt

$after = Dir

# Compare-Object reports all files whose size has changed:

Compare-Object $before $after -property Length, Name Length Name SideIndicator

--- ---- 26 test.txt =>

16 test.txt <=

# Files whose size is unchanged, however, were not recognized

# although they were changed:

"Hey!" > test.txt

$after = Dir

Compare-Object $before $after -property Length, Name

# So, when comparing, it is crucial to select a meaningful

# property, e.g., LastWriteTime:

Compare-Object $before $after -property Length, LastWriteTime, Name

A special form of the "snapshot" is a file's text contents. If you read text contents using Get-Content, you'll get an array with lines of text. Compare-Object can compare this array again and determine which lines within text files have changed: Here's another example:

# Create first test file:

# Compare both files and show only differing lines:

Compare-Object -referenceObject $(Get-Content test1.txt) ` -differenceObject $(Get-Content test2.txt) -includeEqual

InputObject SideIndicator --- ---Hello ==

world ==

beautiful =>

Dans le document Copyright Copyright (Page 140-143)