I'm attempting to create a custom PowerShell object using data from the WebAdministration module for IIS7. The object should capture the ClientIPAddress and SiteID from the GetExecuteRequest WmiMethod for Worker Processes in IIS.
$p = Get-WmiObject WorkerProcess -Namespace root\WebAdministration -ComputerName . | Invoke-WmiMethod -Name GetExecutingRequests | Select-Object -ExpandProperty OutputElement
$wpob = #()
foreach($w in $p)
{
$webrequests = New-Object PSObject
$webrequests | Add-Member -Type NoteProperty -Name ClientIP -Value ($w | select -ExpandProperty ClientIPAddress)
$webrequests | Add-Member -Type NoteProperty -Name SiteID -Value ($W | select -ExpandProperty SiteID)
$wpobj += $webrequests
}
The Problem:
Object ($wpobj) contains the 'ClientIP' and 'SiteID' under get-member, but you cannot get those values by using $wpobj.clientip or $wpobj.siteid. Only way I could retrieve those values were to use $wpobj | select clientip or $wpobj | select siteid
Not being able to get the values for the properties in the above mentioned way makes it more difficult to sort/group the data as I can't select the values later on down the pipeline.
Anyone know what I may be missing? I have not seen this before. Only in this particular case
Solution was to upgrade Powershell to V4.0. IE.invoke won't work on earlier versions of Powershell.
Related
I'm working on a quick string of code that allows me to search a specific print server and also its contents such as printers. What I want for it to do is once getting the printer information to be able to find a specific printer using the port name which in this case is an IP address not quite sure if is possible but I haven't found a command that lets me define a search using those values.
Get-Printer -computerName "server01"|select-object -Property Name, PortName
Name PortName
Printer01 X.XX.XXX.X
Prnter02 X.XX.XX.XX
is there a way to be able to find a printer using the Get-Printer commandlet and utilizing the port name to find the specific printer?
I'm just explaining in more detail #JeffZeitlin very correct answer.
Get-Printer - The Get-Printer cmdlet retrieves a list of printers installed on a computer. You can also use Get-Printer to retrieve the properties of a single printer, and then use that information as input into other cmdlets.
Get-Printer | Get-Member - The Get-Member cmdlet gets the members, the properties and methods, of objects.
Get-Printer | get-member
Get-Printer | Select-Object - The Select-Object cmdlet selects specified properties of an object or set of objects. It can also select unique objects, a specified number of objects, or objects in a specified position in an array.
Get-Printer | select-object -Property Name, PortName
Get-Printer | Select-Object | Where-Object - The Where-Object cmdlet selects objects that have particular property values from the collection of objects that are passed to it. For example, you can use the Where-Object cmdlet to select files that were created after a certain date, events with a particular ID, or computers that use a particular version of Windows.
Get-Printer | select-object -Property Name, PortName | where PortName -eq "PORTPROMPT:"
Get-Printer -ComputerName
Get-Printer -ComputerName $env:Computername | select-object -Property Name, PortName | where PortName -eq "PORTPROMPT:"
Scripting Example Get-Printer
$server = "$env:Computername"
$printersportnames = Get-Printer -ComputerName $server | select-object -ExpandProperty PortName
#Write-Host $printersportnames
$results = New-Object System.Collections.ArrayList # Empty Array
ForEach ($printerportname in $printersportnames) {
$printerportname = $printerportname.ToString()
#Write-Host $printerportname
$output = Get-Printer -ComputerName $server | where-object {$_.PortName -eq $printerportname}
$x = $output.Name
$y = $output.PortName
$z = $output.CommunicationStatus
$a = $output.OperatingStatus
$Object = New-Object PSObject
$Object | Add-Member -Name 'Name' -MemberType Noteproperty -Value $x
$Object | Add-Member -Name 'PortName' -MemberType Noteproperty -Value $y
$Object | Add-Member -Name 'CommStatus' -MemberType Noteproperty -Value $z
$Object | Add-Member -Name 'OperStatus' -MemberType Noteproperty -Value $a
$results += $object
}
$results
Get-NetTCPConnection | Select-Object -Property LocalAddress,LocalPort,RemoteAddress,RemotePort,State,#{name='NameofApp';expression={(Get-Process -id $_.OwningProcess).MainModule.FileVersionInfo.FileDescription}} | Format-Table -AutoSize
The above one works perfectly, Here I want to include the Username as well:
I know that Get-Process -IncludeUserName will return the UserName but I don't know how to join this in the above working command.
Using your current query, here is a simple modified approach that will solve your problem:
Get-NetTCPConnection | ForEach-Object {
$process = Get-Process -Id $_.OwningProcess -IncludeUserName
$description = $process.MainModule.FileVersionInfo.FileDescription
$username = $process.UserName
$properties = $_ | Select-Object -Property LocalAddress,LocalPort,RemoteAddress,RemotePort,State
$properties | Add-Member -Name "NameOfApp" -Type NoteProperty -Value $description
$properties | Add-Member -Name "UserName" -Type NoteProperty -Value $username
$properties
} | Format-Table -AutoSize
Explanation:
Pipe Get-NetTCPConnection through to Foreach-Object.
Get the process object with Get-Process, making sure to include User Names with the -IncludeUserName switch.
Store the descriptions and usernames in separate variables. Not necessary, but I split them up for clarity.
Get all the TCP connection properties that can be selected immediately with Select-Object into a System.Management.Automation.PSCustomObject. This uses the default pipeline variable $_ from Foreach-Object, which is basically the current item from GetNetTCPConnection. You can run Get-Help -Name about_Automatic_Variables to find out more about pipeline variables, and Get-Help -Name about_pipelines for finding out more about pipelines. Unfortunately, these Help files don't contain online versions.
Add the NameOfApp and UserName members to the object with Add-Member.
Format into a table with Format-Table and auto size columns with the -AutoSize switch.
You could also use regular foreach enumeration as well:
& {
foreach ($connection in Get-NetTCPConnection) {
$process = Get-Process -Id $connection.OwningProcess -IncludeUserName
$description = $process.MainModule.FileVersionInfo.FileDescription
$username = $process.UserName
$properties = $connection | Select-Object -Property LocalAddress,LocalPort,RemoteAddress,RemotePort,State
$properties | Add-Member -Name "NameOfApp" -Type NoteProperty -Value $description
$properties | Add-Member -Name "UserName" -Type NoteProperty -Value $username
$properties
}
} | Format-Table -AutoSize
The above is wrapping the foreach loop inside a script block, so you need to use the call operator & to run it. You can read more About Operators and About Script Blocks.
Trying to build a custom object inside a For-EachObject loop.
Here is the code
$infouser = New-Object -TypeName psobject
(Get-ChildItem -Path "\\$poste\C$\Users").Name | ForEach-Object {
$nomcomplet += Get-ADUser -Identity $_ | select-object -ExpandProperty userprincipalname
Add-Member -InputObject $infouser -Name "Code" -Value $_ -MemberType NoteProperty
Add-Member -InputObject $infouser -Name "Nom complet" -Value $nomcomplet -MemberType NoteProperty
}
$infouser | Out-GridView
What i'm trying to achieve is a custom object containing the usernames in C:\USERS along with their equivalent full e-mail adress from the AD.
What I have works partially, it displays the first one it can add, but it doesn't "append" the others :
Giving the error : "Add-Member : Cannot add a member with the name...because a member with that name already exists. If you want to overwrite the member anyway, use the Force parameter to overwrite it."
I don't want to overwrite, I want to append it to the object so the final object contains all usernames and all adresses.
What am I doing wrong here? Thanks
You need to create an array of psobjects, not a single psobject. You're creating a single object and re-adding the properties X times.
This implicitly creates an array and adds a new psobject for each loop.
$infouser = (Get-ChildItem -Path "\\$poste\C$\Users").Name | ForEach-Object {
[pscustomobject]#{
'Code' = $_
'Nom Complet' = $(Get-ADUser -Identity $_ | select-object -ExpandProperty userprincipalname )
}
}
$infouser | Out-GridView
I am trying to create a backup powershell script for user documents. I have created a script where I am putting on a form box the username I want to backup and then the script proceeds. The last thing is that I want to have a rule that if I put a wrong name, the script will not proceed.
Does anyone knows how I can "read" the present useraccounts on a laptop, in order to create rule to cross-check the input with the useraccounts?
Best regards.
This will read all of the folders in C:\Users and attempt to find a corresponding account in AD:
Get-Childitem C:\users -Directory |
ForEach-Object {
$profilePath = $_.FullName
Get-AdUser -Filter {SamAccountName -eq $_.Name} |
ForEach-Object {
New-Object -TypeName PsCustomObject |
Add-Member -MemberType NoteProperty -Name Name -Value $_.Name -PassThru |
Add-Member -MemberType NoteProperty -Name ProfilePath -Value $profilePath -PassThru |
Add-Member -MemberType NoteProperty -Name SID -Value $_.SID -PassThru
}
} | Format-Table Name,SID, profilePath -AutoSize
Obviously you can modify to get different AD properties, if needed. Also, remove the Format-Table command in order to pipe the output objects for further manipulation.
Note:
This requires the AD PowerShell Module to be installed on the system you run the script on.
It only outputs an object if it finds a user account, so you won't see anything for folders it finds that have no account.
Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount='True'" | Select Name
will give you names of local accounts. Other available fields for select are listed here.
Using the example below:
Get-Service | ConvertTo-HTML -Property Name, Status > C:\services.htm
I was wondering if it is possible to alias the property name - the same way you could in SQL:
Example:
Get-Service | ConvertTo-HTML -Property Name AS NEWNAME , Status AS MYNEWSTATUSNAME> C:\services.htm
I know the above syntax wouldn't work... What is the correct way to alias a property name?
How about using select-object?
get-service | select-object -property #{N='MyNewStatus';E={$_.Status}}, #{N='MyNewName';E={$_.Name}} | ConvertTo-HTML > C:\services.htm
The way to alias a property name is to add an AliasPropery to the object.
Get-Service |
foreach {
$_ | Add-Member -MemberType AliasProperty -Name MYNEWSTATUSNAME -Value Status -PassThru
} |
Select Name,MYNEWSTATUSNAME
You could do an intermediate step of creating objects with the property names you want using the new-object cmdlet.
Get-Service | foreach{ new-object PSObject -property #{newname=($_.Name); newstatus=($_.Status)}} | ConvertTo-Html > .\services.htm