I have a script that has two comboboxes. The first selects a location, the second populates depending on the first combobox selecteditem and displays available printer names for that location.
What I see happen more often than not is the list has duplicates of all of its items. Code below;
$Hospital = Get-Printer -ComputerName \\PrintServer | where {$_.Name -like “*Name*”}
$ComboBox_Location.Add_SelectedIndexChanged{
switch ($ComboBox_Location.SelectedItem){
"Hospital"{
$ComboBox_Printer.Items.Clear();
foreach($Name in $Hospital){
$ComboBox_Printer.Items.Add("$($Name.name)");
}
}
I can provide more code if it is needed. I believe the problem is in this particular code, but you can tell me otherwise. I also took out the ("$($Name.name)") and replaced it with "$Name.name", the following are results of the test;
MSFT_Printer(Name="PrinterName")
MSFT_3DPrinter(Name="PrinterName")
They were the same name. It was the duplicate. Is something needing a change in my print server?
Thanks in advance!
I found what was wrong. The devicetype was not defined. It needed to be;
$Hospital = Get-Printer -ComputerName \\PrintServer | where {($_.Name -like “*Name*”) -and ($_.DeviceType -eq "Print")}
This excluded any other types of devices (like the 3DPrinter) from populating in the list.
Related
Below is the code I am working with. I have verified that the initial import-csv is working as it should be, and if I change out the variable object for a concrete object, the script works as it should. It just seems to not recognize/use the variable the way that it should.
$CSVOutput = "C:\temp\output.csv"
$Output = foreach($u in $userlastname)
{
Get-ADComputer -Filter {Description -Like '*$u*'} -properties Description | Select Name, Description
}
$Output | Export-Csv $CSVOutput
If I replace the $u in the filter with one of the values from the $userlastname variable, it works, but it just runs the search with the set value as many times as it runs the foreach loop. I am expecting to see several different computer objects that have the different values from $userlastname in their description. Currently it returns nothing, as if it found no values that matched in the description field.
While it’s technically possible to use a scriptblock as a filter in the ADCommands, it isn’t recommended - use a string instead:
Get-ADComputer -Filter "Description -like '*$($u.name)*'" -Properties ...
Using a string will solve your variable substitution issue.
ETA: Comments indicated that you were getting #{Name=User} as the expansion for $u in the filter expression. This is because $u was a structured [PSCustomObject], and you were looking for a single field from that object. The easiest way to get the value of the desired field of the object is simply to use the PowerShell evaluation construct, as given in the edited answer.
I've got a text file that contains a list of user identities. I want to pass each member on that list to Get-csMeetingMigrationStatus and get back UserPrincipalName, Status and LastMessage. From there I want to output to gridview as an eyes on test for migration status.
I'd like to do this in one pipeline but can't work it out. I know that Get-csMeetingMigrationStatus does not take pipeline input for its parameter -identity so I have to use another means of passing that parameter to the function. I've done things like this before and am wondering if the fact that the list of users is an import from a text file rather than an array created from scratch is the cause.
I needed to get this working asap so thought I'd just put it all in a foreach loop as below. I know the example below doesn't give me all I want regards output but even the sample below fails.
$UserDetails = Get-Content -path c:\test.txt
foreach ($ud in $UserDetails) {
Get-csMeetingMigrationStatus -identity $ud | Select-Object Userprincipalname, status, lastmessage
}
When I run the above the return for the first identity is the property headers for my connect-microsoftteams connection.
Subsequent iterations return a blank line. For each iteration of the foreach loop, if I copy and paste the command in the foreach statement into the terminal window and run it, the correct information for each user is displayed. I don't understand how that can be.
Ultimately I'd like to push all this down a single pipeline and output to gridview.
If anyone can assist with either problem above I'd appreciate it as I've tried sorting this for a good number of hours now and can't find a solution.
Thanks
Use the ForEach-Object cmdlet:
Get-Content -path c:\test.txt |ForEach-Object {
Get-CsMeetingMigrationStatus -identity $_ | Select-Object Userprincipalname, status, lastmessage
} |Out-GridView
Nesting the pipeline inside ForEach-Object means that we can supply another downstream cmdlet (in this case Out-GridView) with whatever output is produced by it (unlike with the foreach(){} loop statement)
I started with this, on a recommendation from a friend
Get-WmiObject win32_product | ft name, version
But then I found this, which gives me pause.
A little research led me to this
wmic product where "Name='Revit 2018'" get name,version
Which works as far as the data gathered. And yes, I am looking for a different program in this example. in any case, once I had good info using WMIC I tried to get the data into a variable so I could get just the version number, but the data formatting is something I have never seen before. I was hoping for a simple solution, like
$object = wmic product where "Name='Revit 2018'" get name,version
$object.version
But only the result is an array with 6 items, and only one seems to be the actual data line, and that's a single line, not two properties. And, I really wonder if an old command line utility is the right answer here. If it really is the best way to do this, is there a trick to converting the raw data to something more, PowerShelly? And if it's not the best way to get this info, what is? Is that scary link real, or is Get-WmiObject win32_product actually safe? And if so, is there a way to filter on a specific name, to speed things up? And indeed, Get-WmiObject doesn't work as I was expecting, as
$object = Get-WmiObject win32_product | ft name, version
foreach ($item in $object) {
Write-Host "$($item.version)"
}
Doesn't work as expected at all.
EDIT: This seems to be working as expected, which is progress.
$version = (Get-WmiObject win32_product -filter:"Name = 'Revit 2018'" | Select-Object -property:*).version
Write-Host "$version!"
I guess the question is really, is this a safe and consistent approach, or is there a better one?
Why not use the registry?
Set-Location HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall
$app = Get-ChildItem | Where-Object { $_.GetValue("DisplayName") -match 'YourSoftware' }
$app.GetValue("DisplayVersion")
Or
Set-Location HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall
$apps = Get-ChildItem
foreach ($app in $apps) {
$app.GetValue("DisplayName","DisplayVersion")
}
Note: You'll also need to check the SysWow64 registry location as well
HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\
Note: Not all items will have a display version in which case you always have the option of looking in the installation directory for the executable itself, which should have a version on it.
We have a big audit coming up, and we want to be sure that all termed employees' AD computer accounts have been deactivated. I have a .csv that has a unique identifier that we use - our schema includes that ID in the middle of the ADcomputer Name property. I am having enormous trouble correctly piping the imported csv objects and their property to the filter. I think. I'm not entirely sure. This is something like what I've been trying.
Import-Csv termname.csv | ForEach-Object
{ Get-ADComputer -Filter { Name -Contains "$($_.id)" } } |
Export-Csv termcomp.csv -NoTypeInformation
This "script" pulled a total of no content, while I KNOW that when I test
Get-ADComputer -Filter { Name -Contains $id }
where $id is that unique ID, I get hits on AD Computer objects. Likewise, testing this block
Import-Csv termname.csv | ForEach-Object { Get-ADComputer { Name -Contains $_.id }
PowerShell's error is:
..."Property 'id' not found in object of type: 'System.Management.Automation.PSCustomObject'.
I think that I am misapprehending what precisely is an "object" in this case. Is the whole imported array an object, with a property of .id? Or is each row its own object, with a .id property? And, either way, why has PowerShell such strong objections to a pipeline object, which is, after all, its primary job?
Is there an entirely better way to go about this whole process? Am I somehow overthinking the whole mess?
UPDATE
As requested, sample contents of the csv file. Taking the suggestion to use wildcards instead, I've put the wildcards into the .csv itself, which, again, may not be the most elegant solution. But as long as it works! Here's the sample, copied from Notepad++
id
*rstarr56*
*jlennon58*
*pmcartney74*
*gharrison68*
So it looks like your CSV file does not have an "ID" heading in it, causing that not to be an available property, easy fix there is to confirm the contents of the CSV file, if everything looks correct try running Import-Csv termname.csv | ForEach-Object { Write-Host $_.id } to confirm that the property is coming across correctly. However you will also have trouble using -Contains here as that operator is meant to check if an array contains a particular value, you'll need to use Name -Like "*$($_.id)*"
After hours of digging, I found an answer here:
Import-CSV and Foreach to use Get-ADUser
Thanks especially to Mike for some great thinking about -Like and how to test the success of the code.
The line that ended up working was:
Import-Csv termname.csv | ForEach-Object {
Get-ADComputer -Filter "Name -Like '*$($_.id)*'"
} | Export-Csv termout.csv
Apparently, Powershell hates {{}}.
Thanks again, all!
I'm writing a script in PowerShell to automate creation of AD users. One of the conditions I use is to check if the user already exists, then to Write-Host "User exists" and move to the next element in the array. However, when I run the script, it gives me an odd behavior. I'll put the code then explain what happens when I put in breakpoints.
$MACList = Get-Content $Path\MACs.txt
foreach ($MAC in $MACList){
$MABName = Get-ADUser $MAC
if ($MABName -ne $null) {
Write-Host "MAB already exists, moving to next"
} else {
# create the new user
}
When I run the script with breakpoints I can see that $MACList contains the MACs in the file. When I move to the next step, I can see that $MAC contains each element as I traverse the $MACList array. When it gets to the $MABName line, $MAC indeed contains a MAC address, so it should go find if I have that user and set $MABName to that user. It seems to keep the same value if the Get-User cmdlet doesn't return an object. Any ideas on why this might happen?
Get-ADUser throws an error for non-existing users, so the variable retains its previous value. Use the -Filter parameter to avoid this issue:
$MABName = Get-ADUser -Filter "SamAccountName -eq '$MAC'"