Get nested values in one line - powershell

I'm new to powershell so I had a simple question. Suppose I have the following powershell code:
$t = Get-SomeData -someParam someParamValue
$t.SomeProperty.SomeNestedField
The second command above will print the value of SomeNestedField, which is nested inside t's property called someProperty
Can I combine these two lines into one powershell command (perhaps through piping), so that the output of the second command comes from just one command overall ?
Requirement is that it should print the value, not assign it to some powershell variable ..
Perhaps something like:
Get-SomeData -someParam someParamValue | SomeProperty | SomeNestedField
Some info that might help out:
Suppose I change above code to this:
$t = Get-SomeData -someParam someParamValue
$u = $t.SomeProperty
$t.GetType()
$u.GetType()
When I execute $t.GetType(), the BaseType listed is a class, but if I do $u.GetType(), it's BaseType is listed as System.ValueType

You can use SELECT aka SELECT-OBJECT
Get-SomeData -someParam someParamValue | select -ExpandProperty SomeProperty
Or ()
(Get-SomeData -someParam someParamValue).SomeProperty.SomeNestedField

Related

Powershell replacing string with multiple values

I am new to powershell. Here are some code examples will help me to explain:
The first example gives the correct output I want which is a list of values, two values in this example, under OrganizationalUnitDistinguishedNames
PS C:\Users\Administrator\Desktop> $test=Get-APSDirectoryConfigList -DirectoryName test.com
PS C:\Users\Administrator\Desktop> $test
CreatedTime DirectoryName OrganizationalUnitDistinguishedNames ServiceAccountCredentials
----------- ------------- ------------------------------------ -------------------------
12/4/2017 9:26:50 AM test.com {OU=t1,DC=acc, OU=t2,DC=test} Amazon.AppStream.Model.ServiceAccountCredentials
PS C:\Users\Administrator\Desktop> $test.OrganizationalUnitDistinguishedNames
OU=t1,DC=acc
OU=t2,DC=test
However, the following command treats two values "OU=t2,DC=test,OU=t1,DC=acc" as a single string. What is the correct syntax to create with two separate values instead of a single string? I have tried different ways (with or without double quotes), they don't work.
PS C:\Users\Administrator\Desktop> $test=New-APSDirectoryConfig -DirectoryName test.com -OrganizationalUnitDistinguishedName "OU=t2,DC=test,OU=t1,DC=acc" -ServiceAcco
untCredentials_AccountName TEST\serviceaccount -ServiceAccountCredentials_AccountPassword secret_password
PS C:\Users\Administrator\Desktop> $test
CreatedTime DirectoryName OrganizationalUnitDistinguishedNames ServiceAccountCredentials
----------- ------------- ------------------------------------ -------------------------
12/4/2017 9:33:25 AM test.com {OU=t2,DC=test,OU=t1,DC=acc} Amazon.AppStream.Model.ServiceAccountCredentials
PS C:\Users\Administrator\Desktop> $test.OrganizationalUnitDistinguishedNames
OU=t2,DC=test,OU=t1,DC=acc
Try:
$OUDNArray = #("OU=t2,DC=test","OU=t1,DC=acc")
$test=New-APSDirectoryConfig -DirectoryName test.com -OrganizationalUnitDistinguishedName $OUDNArray -ServiceAccountCredentials_AccountName TEST\serviceaccount -ServiceAccountCredentials_AccountPassword T3st12345
According to the AWS Appstream Docs:
Parameters
-OrganizationalUnitDistinguishedName <String[]> The distinguished names of the organizational units for computer accounts.
Required? False Position? Named Accept pipeline input? False
The OrganizationalUnitDistinguishedName accepts an array.

Replace Multiple Strings in a SQL File using PowerShell

I am able to replace a single string in a SQL file using PowerShell as follows:
$newPrefix = "foo'
$dbUserMappingScriptPath = "C:\MySQL_Template.sql"
$updatedDbUserMapingScriptPath = "C:\MySQL.sql"
(gc $dbUserMappingScriptPath).Replace('DBPrefix_',$newPrefix) | sc $updatedDbUserMapingScriptPath
This is great for single scenarios, but I need to replace multiple strings. I have tried the following, but it doesn't perform the replace operation beyond replacing the first string of 'DBPrefix_' with $newPrefix. It does not perform the replacements for 'MDFDatabasePath' and 'LDFDatabasePath'.
How do I replace multiple strings given the following snippet? Note that this is wrapped in a Foreach-Object for the $.MDFDatabasePath and $.LDFDatabasePath values.
$dbUserMappingScriptPath = "C:\MySQL_Template.sql"
$updatedDbUserMapingScriptPath = "C:\MySQL.sql"
(gc $dbUserMappingScriptPath).Replace('DBPrefix_',$newPrefix).Replace('MDFDatabasePath',$_.MDFDatabasePath).Replace('LDFDatabasePath',$_.LDFDatabasePath) | sc $updatedDbUserMapingScriptPath
Here is a snippet of my SQL:
USE [master]
GO
CREATE DATABASE [DBPrefix_mydb] ON
( FILENAME = N'MDFDatabasePath\DBPrefix_mydb.MDF' ),
( FILENAME = N'LDFDatabasePath\DBPrefix_mydb.ldf' )
FOR ATTACH
GO
UPDATE: I had a mismatch in my PowerShell script in that I was running the replace on the wrong SQL script. The code above with an extra .Replace works like a charm

Select-Object on imported CSV column with space in name returned empty values

I'm writing a script to process a CSV file created on a non-Windows platform.
The CSV has a lot of columns, not all of which I want.
They are:
TypeName: System.Management.Automation.PSCustomObject
Name
----
Equals
GetHashCode
GetType
ToString
AVGCPUTIME
AVG_CARDS_PN
AVG_CARDS_RD
AVG_ELAPSED
AVG_IO_TIME
AVG_LINES_PRNTD
AVG_OV_MEM
AVG_OV_MEM_INT
AVG_SAV_MEM
AVG_SAV_MEM_INT
BEGINDATE
BEGINTIME
CARDS_PN
CARDS_RD
CPUTIME
DCKEYIN
ELAPSED
ENDDATE
ENDTIME
IO_TIME
JOBNAME
JOBSTATUS
JOBTYPE
LINES_PRNTD
MANUAL
MIXNUM
OV_MEM
OV_MEM_INT
PCJOB
REFNUM
RUNTIME PARAMETERS ...
SAV_MEM
SAV_MEM_INT
SCHEDDATE
SCHEDTIME
SYSTEM
TASKNUM
USERCODE
I have a problem selecting the property, RUNTIME PARAMETERS - both of the following bits of code result in me having a column with the name I expect, but every value in that column is empty (I'm using Out-GridView just now while writing the script, the final script will output data to a new file once I've filtered with Where-Object etc to pull out only the info I need - the intention is for the PowerShell script to run as an automated process when the file lands on the server).
$Inp = Import-Csv K:\LOGSTATS_ALLBATCH_20150602165021.CSV
$Inp| Select USERCODE,JOBNAME,MIXNUM,TASKNUM,BEGINDATE,BEGINTIME,ENDDATE,ENDTIME,DCKEYIN,MANUAL,JOBSTATUS,JOBTYPE,CPUTIME,IOTIME,ELAPSED,SYSTEM,"RUNTIME PARAMETERS"|OGV
$Inp = Import-Csv K:\LOGSTATS_ALLBATCH_20150602165021.CSV
$Inp| Select USERCODE,JOBNAME,MIXNUM,TASKNUM,BEGINDATE,BEGINTIME,ENDDATE,ENDTIME,DCKEYIN,MANUAL,JOBSTATUS,JOBTYPE,CPUTIME,IOTIME,ELAPSED,SYSTEM,#{Name="PARAMS";Expression={$_."RUNTIME PARAMETERS"}}|OGV
Here's a sample of the input:
"REFNUM","USERCODE","JOBNAME","MIXNUM","TASKNUM","BEGINDATE","BEGINTIME","ENDDATE","ENDTIME","SCHEDDATE","SCHEDTIME","DCKEYIN","MANUAL","PCJOB","JOBSTATUS","JOBTYPE","CPUTIME","AVGCPUTIME","IO_TIME","AVG_IO_TIME","ELAPSED","AVG_ELAPSED","SAV_MEM","AVG_SAV_MEM","OV_MEM","AVG_OV_MEM","SAV_MEM_INT","AVG_SAV_MEM_INT","OV_MEM_INT","AVG_OV_MEM_INT","LINES_PRNTD","AVG_LINES_PRNTD","CARDS_RD","AVG_CARDS_RD","CARDS_PN","AVG_CARDS_PN","SYSTEM","RUNTIME PARAMETERS"
01141730,TEST ,CONTROLCARD ,09376,00000,20150601,0106,20150601,0106,20150601,0100,N,N,N,COMPLETEDOK ,SCHEDULED ,0000000000,0000000000,0000000000,0000000000, 0:00:00, 0:00:00,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,0000000000,01234,"BETA" "INCR" "ALL"
And here's an example of the output from the 2nd piece of code, piped through Format-List:
USERCODE : TEST
JOBNAME : CONTROLCARD
MIXNUM : 09376
TASKNUM : 00000
BEGINDATE : 20150601
BEGINTIME : 0106
ENDDATE : 20150601
ENDTIME : 0106
DCKEYIN : N
MANUAL : N
JOBSTATUS : COMPLETEDOK
JOBTYPE : SCHEDULED
CPUTIME : 0000000000
IOTIME :
ELAPSED : 0:00:00
SYSTEM : 01234
PARAMS :
Any help understanding why I'm either not selecting the property with the space in it, or not seeing the values, would be greatly appreciated!
EDIT:
It seems the code was ok but there is a possible issue with the encoding of the header - adding screenshot from hex editor for #Ansgar Wiechers
It seems your input file contains null characters that mess up your field names. You can remove them like this:
$file = 'C:\path\to\your.csv'
(Get-Content $file -Raw) -replace [string][char]0 | Set-Content $file
Removing all null characters should be safe, since your file appears to be ASCII encoded (no BOM in your screenshot).
The removal operation took about a second when I tested it on a 13 MB sample file.
Warning: Do NOT use this on Unicode encoded files (UTF-8, UTF-16, ...) or you'll end up with gibberish in your files.

How can I access properties of the IpPermissions property of Get-EC2SecurityGroup?

I am trying to get a list of security groups. (Successful - Using Get-EC2SecurityGroup)
Get a list of the specific IPPermissions associated with each security group. ( Successful - Using (Get-EC2SecurityGroup).IpPermissions )
Only return results where the FromPort = "xxx" ( Unsuccessful - Not sure how to access the FromPort property that is returned in the result list )
Ultimately what I am trying to accomplish is:
Get a list of existing security groups, and loop through each group.
While looping through each group, call the IpPermissions, and look for the specific FromPort "xxx".
If the FromPort is a match, record the other properties: (FromPort, IpProtocol, IpRanges, ToPort, UserIdGroupPairs)
Problem I am having
I am not sure how to do a loop using the amazon objects
I cant seem to access the properties even though they appear to be named and have values.
I have tried using -Filter with many different iterations, with no success.
The documentation seems self-referencing, and the examples I have run across dont get down to this level of detail.
Results returned from (Get-EC2SecurityGroup).IpPermissions
FromPort : 123
IpProtocol : tcp
IpRanges : {0.0.0.0/0}
ToPort : 123
UserIdGroupPairs : {}
Here's an example that does as you've described:
Filters security group objects by FromPort
Of the matched security groups, output IpProtocol, IpRanges, ToPort, and UserIdGroupPairs.
Code:
# Example using port 22
PS C:\> $port = 22
PS C:\> Get-EC2SecurityGroup |
? { $_.IpPermissions.FromPort -eq $port } |
% { $_.IpPermissions } |
Select -property IpProtocol, IpRanges, ToPort, UserIdGroupPairs
Output:
IpProtocol IpRanges ToPort UserIdGroupPairs
---------- -------- ------ ----------------
tcp {0.0.0.0/0} 22 {}
... ... ... ...

Using "Select" in SharePoint list query

I have a list with a large number of datapoints. (130 columns, 31000 items). I run certain scripts to data-mine and/or update that info. One trick I use to speed up processing time is to pull the whole list into an array at the beginning. This allows powershell to query the array instead of going back to the list each time.
In these scripts I'm usually only searching a few of the fields, making it inefficient to pull all 130+ columns I'm hoping looking for a way to limit what fields are being pulled in.
In the below script, everything works fine until I add the "Select" part of the query. I then get an error of "Unable to index into an object of type System.Management.Automation.PSObject".
Any pointers are greatly appreciated!
$oList = $Web2.Lists["Forecasting data source"]
$aList = $Web.Lists["ArrayTest"]
filter MyFilter {if ($_["CHGTaskRegion"] -eq "Syracuse") {$_}}
$list = $oList.Items | MyFilter | Select ["CHGTaskFacility"],["CHGTicketNumber"]
$list | ForEach-Object {
$ListItem = $aList.Items.Add()
$ListItem["Title"] = [string]$_["CHGTaskFacility"]
$ListItem["Number"] = [string]$_["CHGTicketNumber"]
$ListItem.Update()
}
EDIT:
This is way after the fact but I saw this old post of mine and figured it was worth coming back to. The proper method isn't actually to pull in the whole list and then search it. The right way is to simply get just the items you wanted in the first place using a CAML query. Like so:
$spqQuery = New-Object Microsoft.SharePoint.SPQuery
$spqQuery.Query =
" <Where>
<Eq>
<FieldRef Name='CHGTaskRegion' />
<Value Type='File'>Syracuse</Value>
</Eq>
</Where>"
$spqQuery.ViewFields = "<FieldRef Name='CHGTaskFacility' /><FieldRef Name='CHGTicketNumber' />"
$spqQuery.ViewFieldsOnly = $true
$splListItems = $splList.GetItems($spqQuery)
Have you tried:
$list = $oList.Items | MyFilter | Select {$["CHGTaskFacility"]}, {$["CHGTicketNumber"]}
Add underscore after dollar signs. For some reason _ is not showing up in the code above.
/Pawel
I think the code should be :
$list = $oList.Items | MyFilter | Select CHGTaskFacility,CHGTicketNumber
The way you wrote it, means that you tried to type cast, anything between [ ] being the type.
And so it got confused.
CHGTaskFacility and CHGTicketNumber are properties of the $list of objects, and so Select CHGTaskFacility,CHGTicketNumber is sufficient for Powershell to select them.
UPDATE:
I think the filter code may be incorrect:
filter MyFilter {if ($_."CHGTaskRegion" -eq "Syracuse") {$_}}