Finding out the value of the variable rather than address - powershell-2.0

This is a sample code from PowerShell:
$SPNAME = Read-Host "Please enter Server name with org-root/ls-<SNAME>"
$SN = Get-UcsBlade -AssignedToDn $SPNAME | select Serial
$ChassisID = Get-UcsBlade -AssignedToDn $SPNAME | select ChassisId
Write-Host $SN
Write-Host $ChassisID
$ChassisName = Get-UcsChassis $ChassisID | select UsrLbl
Write-Host $ChassisName
Here the output of the ChassisID is displayed as 1. I want it to display the variable value and not the ID value.

Related

Parsing Info to exe to clear the fields in Hashtag Tables

I'm trying to clear the Fields with values defined in Hash Tables by parsing it to the ipmiutil.exe utility. The script output shows it clear the fields but actually it is not when I manually check it. To clear the Fields values, each of those fields used different parameters as below. Can someone check my wipe code and help with the fix.
This is what I tried and expected the Field Values to clear when found but it is not clearing
Chassis Serial Number = .\ipmiutul.exe fru -G " "
Product Serial Number = .\ipmiutil.exe fru -s " "
Product Asset Tag = .\ipmiutil.exe fru -a " "
Powershell Code:
$fields_to_wipe = [ordered]#{
"Chassis Serial Num" = "fru -G";
"Product Serial Num" = "fru -s";
"Product Asset Tag" = "fru -a"
}
$input = $fru | Select-String -Pattern $fields_to_check | Tee-Object -FilePath "X:\output\fru_result.txt"
Write-Host "Checking FRU Fields for WIPE"
foreach($field in $input)
{
$field = "$field".Substring(0,"$field".IndexOf(":")).Trim()
if($value -eq "")
{
Write-Host $field "is BLANK. WIPE Not Needed."
Write-Host "`n"
}
else
{
if($fields_to_wipe.keys -contains $field)
{
Write-Host "$field Need WIPING"
Write-Host "WIPING $field"
Set-Location "Z:\Tools\Ipmi"
$cmd = .\ipmiutil.exe + {$fields_to_wipe}[$field] + " " + ('" "')
}
else
{
Write-Host $field_to_check ":" $value
}
}
}

How to read a whole column in Powershell

I'm trying to write a powershell script that will output the contents of a column inside a spreadsheet to a txt file. I don't know powershell but I found and figured out how to get a cell, now I need the whole column. The spreadsheet in question has 8K+ rows. Here is what I have so far:
$SMTPApprovedXLS = "c:\temp\SMTP\SMTPAPPLIST.XLS"
$SheetName = "Active"
$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $False
$Workbook = $objExcel.Workbooks.open($SMTPApprovedXLS)
$Worksheet = $Workbook.sheets.item($SheetName)
$startRow = 4
[pscustomobject][ordered]#{
ApprovedIPs = $Worksheet.Cells.Item(4,$startRow).Value()
}
The column is "D" and should start at row 4.
Thanks in advance.
All you have to do is use a loop to run through all the entries and capture the data. Try this:
$SMTPApprovedXLS = "c:\temp\SMTP\SMTPAPPLIST.XLS"
$SheetName = "Active"
$objExcel = New-Object -ComObject Excel.Application
$objExcel.Visible = $False
$Workbook = $objExcel.Workbooks.open($SMTPApprovedXLS)
$Worksheet = $Workbook.sheets.item($SheetName)
$startRow = 4
$ApprovedIPs = #()
$count = $Worksheet.Cells.Item(65536,4).End(-4162)
for($startRow=4; $startRow -le $count.row; $startRow++)
{
$ApprovedIPs += $Worksheet.Cells.Item($startRow, 4).Value()
}
$ApprovedIPs | Out-File C:\ApprovedIPs.txt
Note that the last line is what creates the txt file with the desired data, where C:\ is the directory and ApprovedIPs is the file name. You can just substitute them for your desired location and name of the file.

Parsing a value in powershell

So I run this command
$driverRAIDv = $data|where-object{$_.Name -eq "$serverName" -and ($_.Description1 -match "hpsa")} | select -ExpandProperty version
And it returns this value:
HP HPSA Driver (v 5.0.0-28OEM)
I want to take this value/variable and parse it so that I only have 5.0.0-28OEM
Try this, matches anything between ( and ) brackets:
EDIT: ..and removes the v followed by a space:
$driverRAIDv = $data|where-object{$_.Name -eq "$serverName" -and ($_.Description1 -match "hpsa")} | select -ExpandProperty version
$regex = "(?<=\().*(?=\))"
[regex]::matches($driverRAIDv,$regex).Value -replace "v "
which returns:
5.0.0-28OEM
or you could use following regex which will match anything between (v and )
$regex="(?<=\(v\s).*(?=\))"
Give this a try. Basically, we're creating a "calculated property" that contains an expression to parse out the portion of the value that you want.
$driverRAIDv = $data|where-object{$_.Name -eq "$serverName" -and ($_.Description1 -match "hpsa")} | select -Property #{ Label = 'Version'; Expression = { [void]($_ -match ('v\s(.*?)\)')); $matches[1]; }; };
I tested this out using the following code:
#{ Version = 'HP HPSA Driver (v 5.0.0-28OEM)'} | select -Property #{ Label = 'Version'; Expression = { [void]($_ -match ('v\s(.*?)\)')); $matches[1]; }; };
If you check out the help for the Select-Object command, you will see that you can create calculated properties, which basically modify the value of a property, through a PowerShell expression. To do this, create a Hashtable that contains two items: Label and Expression. The Label can simply be set to the same property value that you're modifying. The Expression is a PowerShell ScriptBlock that performs some type of operation, and returns a result. In the example I gave above, we are running a regular expression against the Version property, and returning it as the result.
You have many ways to do it depending on your needs and variance of what you will get.
One way could be to use replace operator. Say, you got
$driverRAIDv="HP HPSA Driver (v 5.0.0-28OEM)"
$driverRAIDv -replace 'HP HPSA Driver \(v ','' -replace '\)',''
would get you 5.0.0-28OEM
In the same line:
$driverRAIDv = ($data|where-object{$_.Name -eq "$serverName" -and ($_.Description1 -match "hpsa")} | select -ExpandProperty version) -replace 'HP HPSA Driver \(v ','' -replace '\)',''
A non-regex option would be to split on (, ) and (space), and select the last non-empty string.
$driverRAIDv = $data|
where {$_.Name -eq $serverName -and $_.Description1 -match "hpsa"} |
foreach {$_.version.split('[() ]')| where {$_}| select -last 1}

Powershell 2.0 Get users for a local group

How can I get user list from a local group? I only have PS 2.0 and it does not have Get-ADGroup command.
I can get local groups:
$adsi = [ADSI]"WinNT://$env:COMPUTERNAME"
$groups = $adsi.Children | Where { $_.SchemaClassName -eq 'Group' }
$group | ft Name
What I need is to list all the members for each group.
You can try the following
$obj = [ADSI]"WinNT://$env:COMPUTERNAME"
$admingroup = $obj.Children | Where { $_.SchemaClassName -eq 'group'} | where {$_.name -eq 'Administrators'}
$admingroup.Invoke('Members') | % {$_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)}
$admingroup.Invoke('Members') | % {$_.GetType().InvokeMember('Name', 'GetProperty', $null, $_, $null)}
Here are the common properties
String :
Description, FullName, HomeDirectory, HomeDirDrive, Profile, LoginScript, ObjectSID
Integer :
UserFlags, PasswordExpired, PrimaryGroupID
Time :
PasswordAge
You'll find more in Microsoft documentation.
Try this
$computer = [ADSI]"WinNT://$env:COMPUTERNAME"
$computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | foreach {
write-host $_.name
write-host "------"
$group =[ADSI]$_.psbase.Path
$group.psbase.Invoke("Members") | foreach {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}
write-host
}
This doesn't give the domain though, hence i had to look for other ways, like:
If you want to see members of a local group quickly:
PS C:\> net localgroup USERS
Alias name USERS
Comment Users are prevented from making accidental or intentional system-wide changes and can run most applications
Members
-------------------------------------------------------------------------------
NT AUTHORITY\Authenticated Users
NT AUTHORITY\INTERACTIVE
The command completed successfully.
Now you can manipulate this output a bit to get what you need:
$computer = [ADSI]"WinNT://$env:COMPUTERNAME"
$groups = $computer.psbase.children | where { $_.psbase.schemaClassName -eq 'group' } | select -ExpandProperty Name
Foreach($group in $groups)
{
write-host $group
write-host "------"
net localgroup $group | where {$_ -notmatch "command completed successfully"} | select -skip 6
Write-host
}

Text parsing in Powershell: Identify a target line and parse the next X lines to create objects

I am parsing text output from a disk array that lists information about LUN snapshots in a predictable format. After trying every other way to get this data out of the array in a useable manner, the only thing I can do is generate this text file and parse it. The output looks like this:
SnapView logical unit name: deleted_for_security_reasons
SnapView logical unit ID: 60:06:01:60:52:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
Target Logical Unit: 291
State: Inactive
This repeats all through the file with one line break between each group. I want to identify a group, parse each of the four lines, create a new PSObject, add the value for each line as a new NoteProperty, and then add the new object to a collection.
What I can figure out is, once I identify the first line in the block of four lines, how to then process the text from lines two, three, and four. I'm looping through each line, finding the start of a block, and then processing it. Here's what I have so far, with comments where the magic goes:
$snaps = get-content C:\powershell\snaplist.txt
$snapObjects = #()
foreach ($line in $snaps)
{
if ([regex]::ismatch($line,"SnapView logical unit name"))
{
$snapObject = new-object system.Management.Automation.PSObject
$snapObject | add-member -membertype noteproperty -name "SnapName" -value $line.replace("SnapView logical unit name: ","")
#Go to the next line and add the UID
#Go to the next line and add the TLU
#Go to the next line and add the State
$snapObjects += $snapObject
}
}
I have scoured the Google and StackOverflow attempting to figure out how I can reference the line number of the object I'm iterating through, and I can't figure it out. I may rely on foreach loops too much and so that's affecting my thinking, I don't know.
As you say, I think you're thinking too much foreach when you should be thinking for. The below modification should be more along the lines of what you're looking for:
$snaps = get-content C:\powershell\snaplist.txt
$snapObjects = #()
for ($i = 0; $i -lt $snaps.length; $i++)
{
if ([regex]::ismatch($snaps[$i],"SnapView logical unit name"))
{
$snapObject = new-object system.Management.Automation.PSObject
$snapObject | add-member -membertype noteproperty -name "SnapName" -value ($snaps[$i]).replace("SnapView logical unit name: ","")
# $snaps[$i+1] Go to the next line and add the UID
# $snaps[$i+2] Go to the next line and add the TLU
# $snaps[$i+3] Go to the next line and add the State
$snapObjects += $snapObject
}
}
A while loop may be even cleaner because then you can increment $i by 4 instead of 1 when you hit this case, but since the other 3 lines won't trigger the "if" statement... there's no danger, just a few wasted cycles.
Another possibility
function Get-Data {
$foreach.MoveNext() | Out-Null
$null, $returnValue = $foreach.Current.Split(":")
$returnValue
}
foreach($line in (Get-Content "C:\test.dat")) {
if($line -match "SnapView logical unit name") {
$null, $Name = $line.Split(":")
$ID = Get-Data
$Unit = Get-Data
$State = Get-Data
New-Object PSObject -Property #{
Name = $Name.Trim()
ID = ($ID -join ":").Trim()
Unit = $Unit.Trim()
State = $State.Trim()
}
}
}
Name ID Unit State
---- -- ---- -----
deleted_for_security_reasons 60:06:01:60:52:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX 291 Inactive
switch -regex -file C:\powershell\snaplist.txt {
'^.+me:\s+(\S*)' {$SnapName = $Matches[1]}
'^.+ID:\s+(\S*)' {$UID = $Matches[1]}
'^.+it:\s+(\S*)' {$TLU = $Matches[1]}
'^.+te:\s+(\S*)' {
New-Object PSObject -Property #{
SnapName = $SnapName
UID = $UID
TLU = $TLU
State = $Matches[1]
}
}
}
try this
Get-Content "c:\temp\test.txt" | ConvertFrom-String -Delimiter ": " -PropertyNames Intitule, Value
if you have multiple packet try this
$template=#"
{Data:SnapView logical unit name: {UnitName:reasons}
SnapView logical unit ID: {UnitId:12:3456:Zz}
Target Logical Unit: {Target:123456789}
State: {State:A State}}
"#
Get-Content "c:\temp\test.txt" | ConvertFrom-String -TemplateContent $template | % {
[pscustomobject]#{
UnitName=$_.Data.UnitName
UnitId=$_.Data.UnitId
Target=$_.Data.Target
State=$_.Data.State
}
}

Resources