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
Related
Have an odd situation where the PowerShell script below is showing two A records for each SRV record - when there should only be one A record per SRV record. Sample output:
If you're running Active Directory in your environment, simply run the PowerShell script below and you should get the same results. The output file will be on your Desktop. I've re-written this script multiple times and after many trials and errors, still getting the same results. Any idea why the A record is listed twice, and how to get it to show only once?
# Show Active Directory SRV records by Site
$logpath = "$ENV:UserProfile\Desktop\"
####################################################
#find date and convert to string
$date=((Get-Date).ToString('yyyy-MM-dd-HH-mm-ss'))
#defines the path where to find the log file of this script
$Logfile = $logpath+$date+".log"
#convert date and time to string
$date=((Get-Date).ToString('yyyy-MM-dd-HH-mm-ss'))
#get addomain
$domain = ((Get-WmiObject Win32_ComputerSystem).Domain)
#get all sites
$sites = (([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest().Sites).Name)
Function Write-Log
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
Write-Log "Domainname: $domain"
Write-Log "-------------"
foreach ($site in $sites){
$srv = (Resolve-DnsName -Type SRV _ldap._tcp.$site._sites.$domain | ft Name,Type,NameTarget,Port | Out-String)
Write-Log "Sitename: $site"
Write-Log "-------------"
Write-Log "$srv"
}
There might be some differences between the two A-Records, but you're missing them due to this lines here.
$srv = (Resolve-DnsName -Type SRV _ldap._tcp.$site._sites.$domain |
ft Name,Type,NameTarget,Port | Out-String)
The ft command here is an alias for Format-Table, and the default parameter is a list of which Columns to select. In that selection, you're only keeping these fields:
Name
Type
NameTarget
Port
Now, there might be a lot of other fields we're not seeing, and I expect one of them contains some unique different value. So I would suggest you run this to see how it's different. (Maybe this device has two network interfaces and they both have different IPs, and thus both get their own set of DNS settings back from DHCP)
Resolve-DnsName -Type SRV _ldap._tcp.$site._sites.$domain | format-list
That will show you all the fields, and you can figure out why you have two records.
After some trial and error, this gives me exactly what I need. Change:
$srv = (Resolve-DnsName -Type SRV _ldap._tcp.$site._sites.$domain | ft Name,Type,NameTarget,Port | Out-String)
to:
$srv = (Resolve-DnsName -Type SRV _ldap._tcp.$site._sites.$domain | select-object -First 2 | ft Name,Type,NameTarget,Port | Out-String)
Explanantion: The use of select-object allows one to trim off rows from a result object array.
I'm trying to install/activate a MAK key on remote servers. All of them have RemotePS enabled and firewall exception rules in place.
$Results = Invoke-Command -ComputerName Server1 {
$Props = #{ComputerName = $env:ComputerName}
slmgr.vbs /ipk "12345-12345-12345-12345-12345"
$LicStatus = slmgr.vbs /dlv
$Props.Add('LicenseStatus',$LicStatus)
New-Object -TypeName PSObject -Property $Props
}
$Results | Select-Object ComputerName,LicenseStatus
The above does install the MAK key but I don't get any confirmation of this process which is why I've tried adding in the license check option (/dlv) but get nothing returned in the LicenseStatus field. I'm assuming this is because it returns a multi-value maybe!?
Ultimately I'm just trying to get confirmation that the key was installed. There are articles out there about performing this using RemotePS but they all say a notification message is returned for each computer which isn't the case in my experience: https://4sysops.com/archives/change-a-product-key-remotely-with-powershell/
Any ideas how I can check this?
I would call the slmgr.vbs script using Cscript.exe in order to get the results as string array. Otherwise the system will default to using Wscript.exe which is designed to output everything in a messagebox.
Unfortunately, all output of slmgr is localized, so using a regex or something on the LicenseStatus is a no go (on a Dutch NL machine it reads 'Licentiestatus')
What you can do is using switch /dli, because that returns a string array where the last (not empty) value has the status.
Try
$Results = Invoke-Command -ComputerName Server1 {
# install MAK key
$null = cscript.exe "$env:SystemRoot\System32\slmgr.vbs" /ipk "12345-12345-12345-12345-12345"
# test LicenseStatus
$LicStatus = (((cscript.exe "$env:SystemRoot\System32\slmgr.vbs" /dli) |
Where-Object { $_ -match '\S' })[-1] -split ':', 2)[1].Trim()
# return an object
[PsCustomObject]#{
ComputerName = $env:COMPUTERNAME
LicenseStatus = $LicStatus
}
}
$Results
I have a csv file with the following info (for readibility I removed commas) :
box1 1.1.1.1 user password
box2 2.2.2.2 user password
box3 3.3.3.3 user password
I need to execute command with parameters from the csv file, like below :
plink -l user -pw password 1.1.1.1 lsvdisk -delim , -nohdr
and feed a file, with the box name on the start of each line.
In other words, I have ~300 storage boxes (V7k/SVC) and I need an inventory of all the UUID of LUNs. Preferably powershell.
Import-Csv and ForEach-Object are your friend here:
Import-Csv -Header Host,Ip,User,Pw foo.csv | ForEach-Object {
plink -l $_.User -pw $_.Pw $_.Ip lsvdisk -delim ',' -nohdr
}
Note that we have to enclose the , in quotes to ensure it's passed as a single parameter.¹
Within the script block of ForEach-Object $_ is the current object, which has the properties from the CSV file. We had to give the import custom headers since your file apparently doesn't have any. If that's not how your file looks, then adjust accordingly.
This will give you lots of output, of which perhaps the host name is no longer available. Depending on how the output looks, it may make sense to parse it and wrap it up into nice objects, but I don't really know how the output looks. A simple way of simply capturing output and associating it with the host name would be the following:
Import-Csv -Header Host,Ip,User,Pw foo.csv | ForEach-Object {
$output = plink -l $_.User -pw $_.Pw $_.Ip lsvdisk -delim ',' -nohdr
New-Object PSObject -Property #{
Host = $_.Host
Output = $output
}
}
To prefix each line of the output with the host name you can loop over the output again:
Import-Csv -Header Host,Ip,User,Pw foo.csv | ForEach-Object {
$host = $_.Host
plink -l $_.User -pw $_.Pw $_.Ip lsvdisk -delim ',' -nohdr | ForEach-Object {
"${host}: $_"
}
}
¹ If the command line includes lots of things that PowerShell wants to interpret itself, it's often easier to use %-- to stop parsing for the rest of the line after that, which then passes the rest verbatim to external commands.
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)
I am trying to read the host file and trying to ping the each host name and after that capturing the IP address in the response and trying to match with the IP address mentioned in the host file.
I have three scenarios:-
1) Its pinging the host and getting the reply back with the correct IP
Result :-Resolved and Replied
2) It's Not pinging at all and not resolving the IP
Result :-Not Resolved and Not Replied
3) It's Pinging but not resolving the IP correctly mentioned to the IP in the host file
Result :-Not Resolved and Replied
I am trying to achieve that scenario with the below script but not fully achieved as different expression need to be used.
Can someone help me to finish it
$lines = Get-Content myfile.txt | Where {$_ -notmatch "((^#)|(^\s+$))"}
# get all test pairs
$tests=$lines |
ForEach-Object{
$fields = $_ -split '\s+'
echo " Fields are $fields"
for ($i = 1; $i -lt $fields.Length; $i++){
New-Object PsObject -Property #{IP=$fields[0];Host=$fields[$i]}
}
}
$tests |
ForEach-Object{
$props=#{
IPAddress=$_.ip
Hostname=$_.Host
Resolve =' '
Reply = ' '
}
$PingResult = ping -n 1 -w 10 $_.host
#echo "$PingResult"
foreach ($line in $PingResult)
{
if ($line.StartsWith("Pinging") -eq $true)
{
$_.ip= $line -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
echo "IP is $IP"
if ($matches[0])
{
$props.Resolve ='Y'
$props.Reply='Y'
}
else
{
$props.Resolve ='Y'
$props.Reply='N'
}
}
}New-Object PsCustomObject -Property $props
}|
Format-Table -AutoSize | Out-String | Out-File D:\CEP\testlogging.txt
Note:- Cannot use Test-Connection because it throws exception when server wont reply back or doesnot exist and it takes more time to ping.
Thanks.
Suppose it's too late to be of much help but this should resolve the issues you are reporting with Test-Connection.
Test-Connection -ComputerName $IP -Count 1 -ErrorAction SilentlyContinue
That will limit the ping count to 1 and error will be ignored. Then you can work with the object it produces instead of having to parse lines.