How to augment expression into select-object in Powershell? - powershell

I have the following code which prints out some properties of each SQL Server related service on a host:
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement")|Out-Null;
$mc = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer localhost;
$mc.Services | % {$_|select-object Name,DisplayName,ServiceState}
I want to output the result with the HostName appended. I've tried this:
$hostName = hostname
$mc.Services | % {$_|select-object Name,DisplayName,ServiceState,#{Name="HostName";Expression={$hostname}}
But I just get >> displayed. Any ideas on how to accomplish what I want?

I believe you are missing a }:
$hostName = hostname
$mc.Services | % {$_|select-object Name,DisplayName,ServiceState,#{Name="HostName";Expression={$hostname}}}
And you can do it without the foreach-object:
$mc.Services | select-object Name,DisplayName,ServiceState,#{Name="HostName";Expression={$hostname}}

Related

SetEnvironmentVariable from integer held in a csv cell

I have a use case where i want to be able to write a port number to the system environment variable that matches the PC name that the script is being run on.
To do this i have a script that looks for the Computername in a 2 column csv file and writes the corresponding port number of the device to the system environment variable. The problem is that i am unable to get the script to add the port number to the environment variable.
If i put brackets around the $port in the last line. an entry is added but instead of the port number it adds the string $port.
If any one could provide some assistance i'd greatly appreciate it. Thanks in advance.
$COMPUTERNAME = "$env:COMPUTERNAME"
$data = import-csv "C:\PS stuff\Port assign.csv" | Where-Object
{$_."computer" -eq "$COMPUTERNAME"}
$data | Select -ExpandProperty "port" $port
[System.Environment]::SetEnvironmentVariable('TCP_PORT', "$port",
[System.EnvironmentVariableTarget]::User)
$port=Import-Csv -Path 'C:\PS stuff\Port assign.csv'| Where-Object {$_.computer -eq "$COMPUTERNAME"}|Select -ExpandProperty "port"
It seems that the variable $port wasn't being written to due to the way i had structured my code. It has now been changed to the following and all works as required. Thanks for all the assistance.
$COMPUTERNAME = "$env:COMPUTERNAME"
$data = import-csv "C:\PS stuff\Port assign.csv" | Where-Object
{$_."computer" -eq "$COMPUTERNAME"}
$port = $data | Select -ExpandProperty "port"
[System.Environment]::SetEnvironmentVariable('TCP_PORT', "$port",
[System.EnvironmentVariableTarget]::User)

How to Get The Real RecordData from DnsServerResourceRecord Using Powershell?

I'm using PowerShell to extract information from an Active Directory DNS server and I'm having trouble getting to the data I want.
Specifically, I'm trying to get the names of hosts that belong to a particular subnet, 10.104.128.x.
When I use the following commands:
Get-DnsServerResourceRecord -ComputerName AD_DNS_SERVER -ZoneName 104.10.in-addr.arpa -RRType Ptr | Where-Object {$_.HostName -like '*.128'}`
I get output that looks like this:
HostName RecordType Timestamp TimeToLive RecordData
-------- ---------- --------- ---------- ----------
104.128 PTR 10/19/2015 3:00:0... 00:15:00 adl5c260a86ba79.XYZ.net.
11.128 PTR 12/29/2015 6:00:0... 00:15:00 adl3c970e8d7166.XYZ.net.
110.128 PTR 1/29/2012 11:00:0... 00:15:00 nroxitow7tst.ABC.com.
114.128 PTR 1/20/2012 7:00:00 AM 00:15:00 adl5c260a86c29e.ABC.com
What I really want are the first column, (HostName), which has the last two octets of the IP; and the fifth column, (RecordData), which has the name of the host the IP is assigned to.
The hostname is the data I really want/need. And I see it right there!
So I used the select command to pare down the output in the pipe train. New command looks like this:
Get-DnsServerResourceRecord -ComputerName AD_DNS_SERVER -ZoneName 104.10.in-addr.arpa -RRType Ptr | Where-Object {$_.HostName -like '*.128'} | select HostName, RecordData
But the output looks like this:
HostName RecordData
-------- ----------
104.128 DnsServerResourceRecordPtr
11.128 DnsServerResourceRecordPtr
110.128 DnsServerResourceRecordPtr
114.128 DnsServerResourceRecordPtr
Dosen't get me the hostname though. Just the type of object the RecordData is but not the data that the object contains, perhaps?
I also tried piping the output to CSV and got the same result.
Then I tried looking at the DnsServerResourceRecord object properties with Get-Member. That showed me the object had a property called PSComputerName. I thought maybe that would have the name of the host but that came up blank when I tried to select it.
I then Googled around a bit and found a few pages that recommended a few ways to use RecordData.ipv4address to coax the data out of the DnsServerResourceRecordPtr object but I haven't gotten any of them to work yet. Output still prints blanks.
So my question is: does a reliable method exist for getting the actual hostname from a PTR record?
To select the PtrDomainName property from the DnsServerResourceRecordPtr object, use a calculated property:
... |Select-Object HostName, #{Name='RecordData';Expression={$_.RecordData.PtrDomainName}}
Yes it's really weird that you can't just call ToString on the DNS record data, it's all formatted using the PowerShell formatters which you can only access with Format-List or Format-Table, rather than just calling $resourceRecord.RecordData.ToString().
I've added more data types than Krzysztof Madej by just hacking out the PowerShell formatters from the XML file, the details are here.
http://david-homer.blogspot.com/2020/10/getting-text-representation-of.html
$dnsserver = "yourowndnsserver"
$dnszones = Get-DnsServerZone -ComputerName $dnsserver | Select-Object ZoneName
ForEach ($zone in $dnszones) {
$data = New-Object System.Object
$ZoneName = $zone.ZoneName
$data = Get-DnsServerResourceRecord $ZoneName -ComputerName $dnsserver
foreach ($registros in $data) {
$data = $ZoneName
$data += ","
$data += $registros.hostname;
$data += ","
$data += $RecordType = $registros.recordType;
$data += ","
if ($RecordType -like "PTR") {
$data += $registros.RecordData.PtrDomainName
}
elseif ($RecordType -like "A") {
$data += $([system.version]($registros.RecordData.ipv4address.IPAddressToString));
}
elseif ($RecordType -like "CNAME") {
$data += $registros.RecordData.HostNameAlias;
}
elseif ($RecordType -like "NS") {
$data += $registros.RecordData.nameserver;
}
elseif ($RecordType -like "MX") {
$data += $registros.RecordData.MailExchange;
}
elseif ($RecordType -like "SOA") {
$data += $registros.RecordData.PrimaryServer;
}
elseif ($RecordType -like "SRV") {
$data += $registros.RecordData.DomainName;
}
$data | out-file -FilePath $env:TEMP\$(Get-Date -Format dd_MM_yyyy)_DNSRecords.csv -Append
}
}

Powershell output formatting table

I have a line of script
`Connect-hpoa *servername* |get-HPOAServerName |format-list -property Hostname,ServerName`
that gives the following output:
Hostname : gblonblade1 ServerName : {#{Bay=1; ServerName=Absent;
SerialNumber=; Status=; Power=; UID=; Partner=}, #{Bay=2;
ServerName=GBLON1234.ops.test.net; SerialNumber=123456789
Status=OK; Power=On; UID=Off; Partner=}, #{Bay=3;
ServerName=GBLON5678; SerialNumber=987654321; Status=OK; Power=On;
UID=Off; Partner=}, #{Bay=4;ServerName=Absent; SerialNumber=; Status=;
Power=; UID=; Partner=}...}
how can i change the output to view just the Hostname and server name and bay number?
Hostname : gblonblade1
Servername: Absent
Bay=1
Hostname : gblonblade1
Servername: gblon1234.ops.test.net
Bay=2
etc....
Assuming that Get-HPOAServerName produces a property ServerName that contains a list of hashtables (which is what your output looks like), you could transform the output like this:
... | Get-HPOAServerName | % {
$hostname = $_.hostname
$_.Servername | % {
New-Object -Type PSCustomObject -Property $_ |
select -Property *,#{n='HostName';e={$hostname}}
}
}

Powershell, Need to input IP in racadm command

I would like to validate a list of DRAC IP's using racadm. I created a powershell script to go through each IP and the run the racadm to get the sysinfo. I'm very new to powershell and hoping get some assistance in get a result sent to a csv file with serverName and getsysinfo.
$dracList = import-csv .\currentDracList.csv -header("Server_Name","Ilo_drac_ip")
$results = #()
$dracList | % {
$dracIP = $_.Ilo_drac_Ip
$dracProps = #{
racadm -r $dracIP -u root -p P#ssword! Getsysinfo
}
$resultt += New-Object -TypeName psobject -Property $dracProps
}
$Result | export-csv .\dracResults.csv
Currently getting an error:
Missing '=' operator after key in hash literal.
t line:4 char:22
racadm -r <<<< $dracIP -u root -p P#ssword! Getsysinfo
I'm able to run the command one at a time, hoping to come up with a good script to run against IP's.
CSV file contains two columns, "Server_Name","Ilo_drac_ip" as mentioned in the script.
Please let me know if any other information is needed. It would be great to have the Server_Name appear in the results.
Thanks,
Here's how I do it on a Single server. Maybe this can put you a step closer to a solution.
$ipv4 = (racadm getsysinfo -4) | Select-String -Pattern "Current IP Address" |
ConvertFrom-StringData
$result = $ipv4."Current IP Address"
$result

How to select a specific column

I need to extract values of specific column. I need to parse output generated with cmd :
netstat -an |
Select-String "TCP\s+.+\:.+\s+(.+)\:(\d+)\s+(\w+)" |
ForEach-Object {
$key = $_.matches[0].Groups[1].value
$Status = $_.matches[0].Groups[3].value.
Above 2 strings when printed gives me Foreign IP and connection state. I need a column with port no of local IP to which a foreign IP is connected.
If you are running on Windows 8 or Windows Server 2012, you can use the following command examples in Powershell V3:
Pipelining with Select-Object
Get-NetTCPConnection | Select LocalAddress,LocalPort,RemoteAddress,RemotePort
Selecting each property individually
(Get-NetTCPConnection).LocalAddress
(Get-NetTCPConnection).LocalPort
(Get-NetTCPConnection).RemoteAddress
(Get-NetTCPConnection).RemoteAddress
Creating variables using each property
$LocalAddress = (Get-NetTCPConnection).LocalAddress
$LocalPort = (Get-NetTCPConnection).LocalPort
$Remote Address = (Get-NetTCPConnection).RemoteAddress
$RemotePort = (Get-NetTCPConnection).RemoteAddress
These should all come out as lists.
Hope this helps :)
I'm not sure what you mean by a column but I've tweaked your regex and this gets the local and foreign addresses and ports:
netstat -an |
Select-String "TCP\s+(.+)\:(.+)\s+(.+)\:(\d+)\s+(\w+)" |
ForEach-Object {
$LocalAddress = $_.matches[0].Groups[1].value
$LocalPort = $_.matches[0].Groups[2].value
$ForeignAddress = $_.matches[0].Groups[3].value
$ForeignPort = $_.matches[0].Groups[4].value
Write-Output "ForeignAddress: $ForeignAddress `t ForeignPort: $ForeignPort `t LocalAddress: $LocalAddress `t LocalPort: $LocalPort"
}