How can I an Object's Property to a String in Powershell - string

I'm pretty familiar with PHP, Javascript, etc but I'm new to Powershell. I'm trying to get IP addresses and Mac addresses from all the computer's in an active directory. I came across a script that gets an object with all the computer names a lists them through a foreach loop. Inside that loop, I'm trying to run the following:
$colItems = GWMI -cl "Win32_NetworkAdapterConfiguration" -name "root\CimV2" `
comp $objComputer.name -filter "IpEnabled = TRUE"
Obviously, this isn't working since it can't take data from the pipeline. Is there away to take the name property and convert it into a string variable to use within the Get-WmiObject? I've tried declaring a string variable with that $objComputer.name as the value and tried $($objComputer.name), but neither did it for me. Any help would be greatly appreciated.

i think you need a hyphen in front of comp...
$colItems = GWMI -cl "Win32_NetworkAdapterConfiguration" -name "root\CimV2" -comp $objComputer.name -filter "IpEnabled = TRUE"
that could be a copy and paste error...
This works for me though (using a dot):
$colItems =GWMI -cl "Win32_NetworkAdapterConfiguration" -name "root\CimV2" -comp . -filter "IpEnabled = TRUE"
using $objComputer though you could do this
$objComputer = #{ "name" = "." }
Matt

Unfortunately Get-WmiObject doesn't accept pipeline input. Altough passing $objComputer.name is perfectly valid (as long as $objComputer is an object that has a name member) you can assign the name value to a vraible and pass the variable to the ComputerName property.
foreach($objComputer $computers)
{
$name = $objComputer.name
$colItems = GWMI -cl Win32_NetworkAdapterConfiguration -comp $name -filter "IpEnabled = TRUE"
$colItems
...
}

Related

How do condition mid-string

I have a string in my psobject and it will only apply for 10 devices but not the 11th one. How do I construct a string and not include one variable if it's the 11th one?
This is what works for the first 10 in my foreach:
$INFO_Tab = New-Object psobject -Property $([ordered]#{
DEVICE = "$($currentDevice)"
Platform = "Name"
Device_Error_Description = "ErrorCodeList files \Retail\Tools\ServiceEndToEnd\ErrorCodeList "
OCP_Display = "sdkDesc in $BaseName $($cppFile)" #$BaseName doesn't apply for $currentDevice="Scanner"
...
})
$xlsx = $INFO_Tab | Export-Excel -Path $outFilePathExcel -WorksheetName "Source" -Autosize -AutoFilter -FreezeTopRow -BoldTopRow -PassThru
Can I do something like this for the OCP_Display line? I can't find an example.
OCP_Display = "sdkDesc in"+ if($currentDevice="Scanner"):"":$BaseName +$($cppFile)"
This is with PowerShell 5.1 and VSCode.
Wrap the if statement in a subexpression $():
"sdkDesc in $(if($currentDevice -ne 'Scanner'){"$BaseName "})$($cppFile)"
It looks like you need $() not just () even outside a string. Aside from that, it helps to know powershell basics.
$currentdevice = 'Unscanner'
$basename = 'Basename'
$cppfile = 'Cppfile'
"Prefix" + $(if($currentDevice -eq "Scanner"){""}else{$BaseName}) + $cppFile
PrefixBasenameCppfile
$currentdevice = 'scanner'
"Prefix" + $(if($currentDevice -eq "Scanner"){""}else{$BaseName}) + $cppFile
PrefixCppfile

Extract string without spacing in powershell cmdlet

I have some powershell script . Instead totalcmd* you can type another process you want.
$tc = get-process -Name totalcmd* | format-wide -property Name
echo $tc
if ($tc -eq "Totalcmd64")
{
Stop-Process -Name totalcmd*
}
Start-Sleep 10
It doesn't work, I think, because, my $tc not equal to string "totalcmd". How can I remove unwanted spaces of cmdlet get-process -Name totalcmd* | format-wide -property Name output and compare strings correctly?
You do not end up with a string because you pipe to format-wide. These cmdlets are best for representing data on the screen. Instead select the property and use -ExpandProperty to return it as a string:
$tc = get-process -Name totalcmd* | Select-Object -ExpandProperty Name
echo $tc
...
You are generally correct that $tc is not equal to "totalcmd" and that is because when you set $tc, you are creating an array (most likely of one element). You can test that by running $tc | get-member to see what kind of object you are working with.
To work with string objects, you could use the Out-String cmdlet as well.
If you want to explicitly stop TotalCmd64 processes why not simply use:
Get-Process -Name TotalCmd64 | Stop-Process
If you want to switch between 64/32bit versions of the program, use a switch statement (untested):
$tc = (Get-Process -Name TotalCmd*).Name
switch ($tc){
'TotalCmd' {Get-Process -Name TotalCmd |Stop-Process;"Start TotalCmd64";Break}
'TotalCmd64' {Get-Process -Name TotalCmd64|Stop-Process;"Start TotalCmd32";Break}
default {"No TotalCmd* processes found"}
}

Powershell - replace string in file

I'm trying to edit the contents of a config file called prefs.cfg. It has two lines:
Server.Name "test"
VoIP.Enabled "1"
I'm trying to get more comfortable with replacing string but I seem to keep messing up.
I wrote something out, I would appreciate if someone could point in my script where I'm going wrong .
$prefs = Get-Content .\prefs.cfg
$prefs | Select-String "Server.Name"
$servername = Read-Host -Prompt "Enter Server Name"
Write-Host $servername
$prefs -replace $servername
$prefs
Although you are passing $prefs to Select-String and -replace, the results of those operations are not being assigned to variables. So you cannot use them later.
One argument is being passed to -replace. It expects two: what to replace, and what to replace it with. Edit: if a single argument is provided, this is taken as "what to replace". As "what to replace it with" is not provided, it will be replaced with nothing (i.e. deleted)
Select-String and -replace use regex. Seems a bit overkill for this task. Where-Object and .Replace are perfectly up to the task.
$prefs = Get-Content .\prefs.cfg
# Get the line using Where. * is wildcard
$oldServerLine = $prefs | Where-object {$_ -like "Server.Name*"}
$servername = Read-Host -Prompt "Enter Server Name"
Write-Host $servername
# Replace old line with new line. ` is the escape character so you get " as expected.
$newPrefs = $prefs.Replace($oldServerLine,"Server.Name `"$servername`"")
$newPrefs
Related: difference between -replace and .Replace

Build URL string

Trying to build a link with a variable and a string, but I always get a space in between them. How can I fix this?
The $sub is a SPWeb object from sharepoint.
Write-Host $sub.Url "/default.aspx"
result:
https://intra.mycompany/pages/sales /default.aspx
Put the $sub variable inside the string literal so that it is treated as one string:
Write-Host "$($sub.Url)/default.aspx"
Note that you will need to use a sub expression operator $(...) since you are accessing an attribute of $sub.
Another approach, depending on how complicated your string is, is to use the -f format operator:
Write-Host ("{0}/default.aspx" -f $sub.Url)
If you have many variables that you need to insert, it can make for cleaner and easier to read code.
Use the URL class' constructor to do the join, rather than using string manipulation. This will have the additional advantage of automatically take care of appending any slashes required.
function Join-Uri {
[CmdletBinding()]
param (
[Alias('Path','BaseUri')] #aliases so naming is consistent with Join-Path and .Net's constructor
[Parameter(Mandatory)]
[System.Uri]$Uri
,
[Alias('ChildPath')] #alias so naming is consistent with Join-Path
[Parameter(Mandatory,ValueFromPipeline)]
[string]$RelativeUri
)
process {
(New-Object -TypeName 'System.Uri' -ArgumentList $Uri,$RelativeUri)
#the above returns a URI object; if we only want the string:
#(New-Object -TypeName 'System.Uri' -ArgumentList $Uri,$RelativeUri).AbsoluteUri
}
}
$sub = new-object -TypeName PSObject -Property #{Url='http://demo'}
write-host 'Basic Demo' -ForegroundColor 'cyan'
write-host (Join-Uri $sub.Url '/default.aspx')
write-host (Join-Uri $sub.Url 'default.aspx') #NB: above we included the leading slash; here we don't; yet the output's consistent
#you can also easily do this en-masse; e.g.
write-host 'Extended Demo' -ForegroundColor 'cyan'
#('default.aspx','index.htm','helloWorld.aspx') | Join-Uri $sub.Url | select-object -ExpandProperty AbsoluteUri
Above I created a function to wrap up this functionality; but you could just as easily do something such as below:
[string]$url = (new-object -TypeName 'System.Uri' -ArgumentList ([System.Uri]'http://test'),'me').AbsoluteUri
Link to related documentation: https://msdn.microsoft.com/en-us/library/9hst1w91(v=vs.110).aspx

Custom Objects to CSV PowerShell

#Function to get the computerlist: Name,OS,IPv4, IPv6,DiskInfo
function Get-ComputerListnDiskInfo{
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline=$True)] [string[]]$ComputerName
)
BEGIN {
Import-Module ActiveDirectory -Cmdlet Get-ADComputer -ErrorAction SilentlyContinue
}
PROCESS {
try{
$computerinfo = Get-ADComputer -Filter * -Properties OperatingSystem
#Information about Name,Ipv4,IPv6,Device,VolumeName,Free,Busy,Size,Pfree,Pbusy for ALL COMPUTERS container
$AllComputerInfo = #()
foreach ($comp in $computerinfo){
#Testing if computers is ON LINE
$TestCon = Tester $comp.name
$test = $TestCon.BooleanV
if($test) {
#write-output "$Test"
$PhysicalDisks = Get-WMIObject -computername $comp.name -query "SELECT * from win32_logicaldisk where DriveType = 3" | Select Deviceid,VolumeName,FreeSpace,Size
$Target = #()
#Create the Object foreach disk and append in the Target Variable
$GetOPNHealthStatus = Get-PhysicalDisk | select FriendlyName,OperationalStatus,HealthStatus
Write-Output "$PhysicalDisk.count"
#write-output $GetOPNHealthStatus.OperationalStatus
$i=0
foreach ($disk in $physicalDisks){
#Get all Items: size,free,busy,pfree and pbusy disk space info (can add a number at the end to set decimals)
$Size=FormatNSetSizeFreeSpace $disk.Size
$Free=FormatNSetSizeFreeSpace $disk.FreeSpace
$Busy=FormatNSetBusySpace $disk.Size $disk.FreeSpace
$Pfree=PercentFreeBusy $Free $size
$PBusy=PercentFreeBusy $Busy $size
#Create a new Object using all the info
$result =New-Object PSObject -Property #{
Device=$disk.DeviceID
VolumeName=$disk.VolumeName
Size=$Size
Free=$Free
Busy=$Busy
Pfree = $PFree
PBusy = $PBusy
OPStatus = $GetOPNHealthStatus.OperationalStatus[$i]
HStatus = $GetOPNHealthStatus.HealthStatus[$i]
}
$i++
#add this info to the target array
$Target+= $result
}
#Add all info into new object
$allIComnDiskInfo=New-Object PSObject -Property #{
Name = $comp.Name
OS = $comp.OperatingSystem
IPV4 = $TestCon.IPv4
IPV6 = $TestCon.IPv6
disksInfo = $Target
}
#and Fill any just add this info to the $Allcomputer info (just online computer's)
$AllComputerInfo+= $allIComnDiskInfo
}
}
return $AllComputerInfo
}
Catch{
Write-Warning $_.Exception.Message
}
}
}
$test = Get-ComputerListnDiskInfo
running $test
$test = Get-ComputerListnDiskInfo
$test
disksInfo : {#{PBusy=8,148; VolumeName=; Busy=10,306; Pfree=91,853; Free=116,178; Device=C:; Size=126,483; OPStatus=O; HStatus=H}}
Name : DC2012
OS : Windows Server 2012 R2 Standard
IPV4 : 192.168.1.251
IPV6 : fe80::cd63:76bf:3d2b:340f%12
And running
$test | Export-Csv here.csv
I got this:
#TYPE System.String
"Length"
"6"
Why is happening this?
Why I don't get all this info?
And how should I search the info contained in the "diskInfo" variable
I tried to pass this $test variable to another function to format it and It seem not to work:
Thank you in advance for the answers
To start out with, you aren't just outputting a custom object, or an array of custom objects. But that's not the first problem I see. The first problem I see is that you have this big function that has a parameter, and then you do this:
$test = Get-ComputerListnDiskInfo
So you call that function with no arguments, so it has no computer to run it against. Some of the parts of the function will probably default to the local computer, but will they all? I don't know, maybe.
So what does $test actually contain? An array. Of what? Well, the first thing that the function outputs is a string:
Write-Output "$PhysicalDisk.count"
So the first item in your array is a string. Then you build a bunch of custom objects and arrays, and what not, and you Return those. Great, the next item in your $test array is a custom object. But $test is not an array of custom objects, or a single custom object, it is an array with a variety of things within it.
That is why Export-CSV will not work.
Basically the issue is this one:
I have an system.object[] in the output while using CSV.
object or similar output when using export-csv

Resources