I am having trouble with object comparison.
I have an application which spits out JSON data. Each time I run my script, I will get the current values and import the stored values from the previous run (either from a .json or .xml file). At the end of the script, I will overwrite the stored values with the current values. The data looks like this:
Stored values:
id : 6549888
description : Windows CPU via WMI
name : Test
dataPoints : {#{id=6314; dataSourceId=6549888; name=CPUBusyPercent; description=%
of Busy CPU; alertTransitionInterval=8; alertClearTransitionInterval=0; type=2; dataType=2;
maxDigits=4; postProcessorMethod=expression;
postProcessorParam=100-(PercentProcessorTime/100000); rawDataFieldName=; maxValue=; minValue=0;
userParam1=; userParam2=; userParam3=; alertForNoData=3; alertExpr=>= 50 60 70; alertSubject=CPU
alert on ##HOST##; alertBody=The host ##HOST## is in state ##LEVEL##. CPU is ##VALUE## percent
busy - it has been in this state since ##START##, or for ##DURATION##}}
Current values:
id : 6549888
description : Windows CPU via WMI
name : Test
dataPoints : {#{id=6314; dataSourceId=6549888; name=CPUBusyPercent; description=%
of Busy CPU; alertTransitionInterval=8; alertClearTransitionInterval=0; type=2; dataType=2;
maxDigits=4; postProcessorMethod=expression;
postProcessorParam=100-(PercentProcessorTime/100000); rawDataFieldName=; maxValue=; minValue=0;
userParam1=; userParam2=; userParam3=; alertForNoData=3; alertExpr=>= 90 95 98; alertSubject=CPU
alert on ##HOST##; alertBody=The host ##HOST## is in state ##LEVEL##. CPU is ##VALUE## percent
busy - it has been in this state since ##START##, or for ##DURATION##}}
In this example, someone changed the alertExpr from "50 60 70" to "90 95 98" and I need to catch that (along with changes made to the rest of the properties).
When I run a foreach loop, I am not getting back any differences, but when I look at a single property, Powershell does report the difference. So the following returns nothing:
foreach ($dataSource in $currentDataSources) {
foreach ($recordedDatasource in $previousDataSources) {
If ($dataSource.id -eq $recordedDatasource.id) {
Compare-Object $dataSource $recordedDatasource
}
}
}
But looking at the index 1034 (that's my test item) does show a difference:
Compare-Object $currentDataSources[1034].datapoints.alertexpr $previousDatasources[1034].datapoints.alertexpr
What is the best way to check each of the properties between my to sets of data?
Thanks.
Related
I am currently developing a backup manager for Hyper-V using PowerShell.
I ran into problems when starting an export job like this:
$job = (export-vm -name "Windows 10" -path F:\VM_Backup\ -asjob)
Now when querying the progress of the job I realized that two objects are inside my Progress property:
> $job.progress
ActivityId : 0
ParentActivityId : -1
Activity : Export wird ausgeführt
StatusDescription : Gelöscht
CurrentOperation :
PercentComplete : 1
SecondsRemaining : -1
RecordType : Processing
ActivityId : 0
ParentActivityId : -1
Activity : Export wird ausgeführt
StatusDescription : Gelöscht
CurrentOperation :
PercentComplete : 37
SecondsRemaining : -1
RecordType : Processing
While the second progress update makes real progress (increasing percentage), the first one always stays like above.
I have never seen this behavior before and that really doesn't make any sense to me. How do I (programmatically) select the "right" job?
By design, the .Progress property collects all progress messages written by the job - it doesn't just reflect the latest status.
The most recently written message is the last one added to the .Progress collection, so you can use index [-1] to retrieve it.
$job.Progress[-1]
Note: For Start-Job-created jobs, you must access the .Progress property on the (one and only) child job instead: $job.ChildJobs[0].Progress[-1] - see about_Job_Details.
I'm working with a private cloud platform that is used for creating and testing Virtual Machines. They have rich API which allows me to create VMs:
{
"name": "WIN2016-01",
"description": "This is a new VM",
"vcpus": 4,
"memory": 2147483648,
"templateUuid": "sdsdd66-368c-4663-82b5-dhsg7739smm",
...
}
I need to automate this process of creating machines by just simply iterating -01 part, so it becomes:
"name": "WIN2016-01",
"name": "WIN2016-02",
"name": "WIN2016-03"
etc.
I tried to use Postman Runner and build the workflow https://learning.getpostman.com/docs/postman/collection_runs/building_workflows/ but with no luck - not sure what syntax I need to use in Tests tab.
This is one way of doing it.
Create a collection and your POST request.
In your pre-request, add the following:
/* As this will be run through the Collection Runner, this extracts
the number of the current iteration. We're adding +1, as the iteration starts from 0.*/
let count = Number(pm.info.iteration) + 1;
//Convert the current iteration number, to a '00' number format (will be a string)
let countString = ((count) < 10) ? '0' + count.toString() :
count.toString();
//Set an environment variable, which can be used anywhere
pm.environment.set("countString", countString)
In your POST request body, do something like this:
{
"name": "WIN2016-{{countString}}",
...
}
Now, run your collection through the 'Collection Runner', and enter the number of Iterations (e.g. how many times you want your collection to run). You can also add a Delay, if your API imposes rate limits.
Finally, click Run.
I'm trying to recreate the information displayed for the current Wi-Fi network when option-clicking on the Wi-Fi status bar item. One of the parameters shown is the MCS Index, but I can't find any way to query this value using the CWInterface class, which is where I am getting most of the other data:
if let interface = CWWiFiClient.shared().interface() {
rssi = interface.rssiValue()
noise = interface.noiseMeasurement()
// etc.
}
Since both the Wi-Fi status bar item and the airport command line tool display the MCS Index, it seems like there should be some way to query it:
MacBook:~ mark$ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I
agrCtlRSSI: -46
agrExtRSSI: 0
agrCtlNoise: -90
agrExtNoise: 0
state: running
op mode: station
lastTxRate: 878
maxRate: 1300
lastAssocStatus: 0
802.11 auth: open
link auth: wpa2-psk
BSSID: xx:xx:xx:xx:xx:xx
SSID: MyWiFi
MCS: 7
channel: 149,80
I've also seem some Python sample code that seems to indicate that the MCS Index should be available, but I don't see it in the docs or code completion.
Is there some way to get this value through Core WLAN or some other framework, or is this something I need to calculate based on other values?
I found another Python script wifi_status.py
which reports the WiFi status. From the lines
def wifi_status(properties=('bssid', 'channel', 'txRate', 'mcsIndex', 'rssi', 'noise')):
xface = CWWiFiClient.sharedWiFiClient().interface()
while True:
yield({name: getattr(xface, name)() for name in properties})
one can conclude that these attributes can be retrieved with
Key-Value Coding.
And that really works:
if let iface = CWWiFiClient.shared().interface() {
if let mcsIndex = iface.value(forKey: "mcsIndex") as? Int {
print(mcsIndex)
}
}
But I have now idea if that approach is officially supported,
or will work in the future, so use at your own risk.
I have and existing PowerShell script (not written by me!) which is designed to use a passed-in parameter (SCOM Alert ID) to then set additional information in the alert, e.g. $alert.CustomField1 = $alert.PrincipleName etc etc.
I am looking to add functionality to this script to be able to add additional 'custom' information which is stored in a separate text/CSV file. The text/CSV file has header line
ServerName,ServiceOwner,Application Tier
so a row in the file would be
MYSERVER.CONTOSO.COM,Joe Bloggs, Tier 1
There will be one unique row for each server in our environment (over 600 rows).
So what I need to do is using the passed-in alert ID. I can use $alert.PrincipleName to find the corresponding row in the text file and pull in the additional details stored in field 2 and 3, i.e. ServiceOwner and ApplicationTier.
This logic holds for the majority of alerts but IF server name is a specific value (e.g. MYSTSERVER.CONTOSO.COM) then instead of using $alert.PrincipleName to match servername in text file, I need to match on another alert property $alert.MonitoringObjectDisplayName. However, the server name in this field is part of a larger string in the format, e.g. User Services Watcher for Pool [MYTARGETSERVER.CONTOSO.COM] - so I need to extract the severname from between the square brackets of the string to then perform the match with the text file.
Hopefully I have explained what I'm trying to do clearly - if not I'm happy to provide further clarification and can also post up the existing PS Script I'm trying to modify if thats any help.
You can react to the server name like this:
$csv = Import-Csv 'C:\path\to\your.csv'
...
if ( $alert.PrincipalName -eq 'MYSTSERVER.CONTOSO.COM' ) {
if ( $alert.MonitoringObjectDisplayName -match '.*\[(.*?)\]' ) {
$targetserver = $matches[1]
}
} else {
$targetserver = $alert.PrincipalName
}
$newdata = $csv | ? { $_.ServerName -eq $targetserver } `
| select ServiceOwner, 'Application Tier'
...
$alert.CustomField2 = $newdata.ServiceOwner
$alert.CustomField3 = $newdata.'Application Tier'
...
lets say I have a text file with lines as such:
[4/20/11 17:07:12:875 CEST] 00000059 FfdcProvider W com.test.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on D:/Prgs/testing/WebSphere/AppServer/profiles/ProcCtr01/logs/ffdc/server1_3d203d20_11.04.20_17.07.12.8755227341908890183253.txt com.test.testserver.management.cmdframework.CmdNotificationListener 134
[4/20/11 17:07:27:609 CEST] 0000005d wle E CWLLG2229E: An exception occurred in an EJB call. Error: Snapshot with ID Snapshot.8fdaaf3f-ce3f-426e-9347-3ac7e8a3863e not found.
com.lombardisoftware.core.TeamWorksException: Snapshot with ID Snapshot.8fdaaf3f-ce3f-426e-9347-3ac7e8a3863e not found.
at com.lombardisoftware.server.ejb.persistence.CommonDAO.assertNotNull(CommonDAO.java:70)
Is there anyway to easily import a data source such as this into protovis, if not what would the easiest way to parse this into a JSON format. For example for the first entry might be parsed like so:
[
{
"Date": "4/20/11 17:07:12:875 CEST",
"Status": "00000059",
"Msg": "FfdcProvider W com.test.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I",
},
]
Thanks, David
Protovis itself doesn't offer any utilities for parsing text files, so your options are:
Use Javascript to parse the text into an object, most likely using regex.
Pre-process the text using the text-parsing language or utility of your choice, exporting a JSON file.
Which you choose depends on several factors:
Is the data somewhat static, or are you going to be running this on a new or dynamic file each time you look at it? With static data, it might be easiest to pre-process; with dynamic data, this may add an annoying extra step.
How much data do you have? Parsing a 20K text file in Javascript is totally fine; parsing a 2MB file will be really slow, and will cause the browser to hang while it's working (unless you use Workers).
If there's a lot of processing involved, would you rather put that load on the server (by using a server-side script for pre-processing) or on the client (by doing it in the browser)?
If you wanted to do this in Javascript, based on the sample you provided, you might do something like this:
// Assumes var text = 'your text';
// use the utility of your choice to load your text file into the
// variable (e.g. jQuery.get()), or just paste it in.
var lines = text.split(/[\r\n\f]+/),
// regex to match your log entry beginning
patt = /^\[(\d\d?\/\d\d?\/\d\d? \d\d:\d\d:\d\d:\d{3} [A-Z]+)\] (\d{8})/,
items = [],
currentItem;
// loop through the lines in the file
lines.forEach(function(line) {
// look for the beginning of a log entry
var initialData = line.match(patt);
if (initialData) {
// start a new item, using the captured matches
currentItem = {
Date: initialData[1],
Status: initialData[2],
Msg: line.substr(initialData[0].length + 1)
}
items.push(currentItem);
} else {
// this is a continuation of the last item
currentItem.Msg += "\n" + line;
}
});
// items now contains an array of objects with your data