Basically, just create a regular Smart Label in the Web GUI, and use System Name matches regex then the machine names separated by a pipe.
Example:
If you have a list separated by a new line or a csv of names, then you can use Notepad++ with the below Find/Replace to convert the list to the Regex query needed:
Original blog below:
------------------------------------------------------------------------------------------------------------------------------
While it's not ideal, sometimes it is required to deploy software based solely off of a list of machines provided by a user. Where I work, I am often given a list of 20-30 machines that need software deployed to them for testing purposes before it goes out to a larger (and more easily targeted) group.
While it's not ideal, sometimes it is required to deploy software based solely off of a list of machines provided by a user. Where I work, I am often given a list of 20-30 machines that need software deployed to them for testing purposes before it goes out to a larger (and more easily targeted) group.
There are multiple ways to handle this. For example, you could put the machines in an OU or an AD member group and create an LDAP label, you could have the users create a text file and create a custom inventory rule, you could upload a csv with an additional field to the asset records of those machines (I have been told this is the supported workaround.), you could type each machine name in manually to the Managed Installation or Script, you could apply a manual label to each machine, etc.
While all of these get the job done, I decided I would post a quick how-to on how I choose to handle this.
In a nutshell, I wrote a Powershell script that takes a list of machine names from a text file (separated by a new line) and generates a SQL query that can then be turned into a Smart Label.
Here is the code (Requires Powershell 5):
#REM This will generate a SQL query for multiple machine names in a text file Function Get-InputFile($initialDirectory = "C:\") { [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog $OpenFileDialog.Title = "Select the text file containing host names" $OpenFileDialog.Multiselect = $false $OpenFileDialog.initialDirectory = $initialDirectory $OpenFileDialog.filter = "TXT (*.txt)| *.txt" $OpenDialogClick = $OpenFileDialog.ShowDialog() If ($OpenDialogClick -eq "OK") { Return $OpenFileDialog.FileName } Else { Write-Warning "Operation cancelled by user." Exit } } Function Get-SavePath($initialDirectory = "C:\") { [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog $SaveFileDialog.Title = "Select where to save the SQL Query" $SaveFileDialog.initialDirectory = $initialDirectory $SaveFileDialog.filter = "TXT (*.txt)| *.txt" $SaveDialogClick = $SaveFileDialog.ShowDialog() If ($SaveDialogClick -eq "OK") { Return $SaveFileDialog.FileName } Else { Write-Warning "Operation cancelled by user." Exit } } #Prompt for input text file $InputFile= Get-InputFile #Get machine names from specified file $Machines= Get-Content $InputFile | Sort-Object if ($Machines -eq $null) { Write-Error "The selected text file is blank." Exit } [int]$MachineCount = $Machines.Count if ($MachineCount -eq 1) { $Prompt = Read-Host -Prompt "The selected text file only has one line. Continue? Yes/No" while("yes","no" -notcontains $Prompt) { Write-Warning "Please type either ""Yes"" or ""No""" $Prompt = Read-Host -Prompt "The selected text file only has one line. Continue? Yes/No" } if ($Prompt -eq "Yes" -or $Prompt -eq "yes") { $SavePath = Get-SavePath New-Item -ItemType File -Path $SavePath -Force | Out-Null Out-File -NoClobber -NoNewline -Append -InputObject "SELECT MACHINE.NAME AS SYSTEM_NAME, SYSTEM_DESCRIPTION, MACHINE.IP, MACHINE.MAC, MACHINE.ID as TOPIC_ID FROM MACHINE WHERE (MACHINE.NAME =""$Machine"")" -FilePath $SavePath Exit } elseif ($Prompt -eq "No" -or $Prompt -eq "no") { Write-Warning "Operation cancelled by user." Exit } } #Prompt for path to save output $SavePath = Get-SavePath New-Item -ItemType File -Path $SavePath -Force | Out-Null [int]$Count = 0 Out-File -NoClobber -NoNewline -Append -InputObject 'SELECT MACHINE.NAME AS SYSTEM_NAME, SYSTEM_DESCRIPTION, MACHINE.IP, MACHINE.MAC, MACHINE.ID as TOPIC_ID FROM MACHINE WHERE (' -FilePath $SavePath foreach ($Machine in $Machines) { $Count = ($Count + 1) if ($count -eq $MachineCount) { Out-File -NoClobber -NoNewline -Append -InputObject "(MACHINE.NAME =""$Machine""))" -FilePath $SavePath } else { Out-File -NoClobber -NoNewline -Append -InputObject "(MACHINE.NAME =""$Machine"") OR " -FilePath $SavePath } }
I usually just right click the PS1 and Run with Powershell, but feel free to do what you want with it.
It will first prompt for the input file. This file should be formatted with each machine name on a new line.
Example:
MACHINE1
MACHINE2
MACHINE3
The script will then prompt for the directory and file name to save the output.
After you have the SQL query, you will need to create a Device Smart Label in the K1000.
or
At this point, we'll just need to create a regular Smart Label. I usually just leave the default search criteria, name the label, and hit Save.
Then go to Label Manangement - Smart Labels, and click the link for the new label you created (not the pencil icon).
Now click "Edit SQL", and then replace the entire text block with the SQL query from the Powershell script.
Then hit save, and wait for devices to check in to get the label!
As of right now, I'm not aware of another way to create a SQL smart label. If you have found a better way, then please let me know!
Of course there are downsides to this. The machine won't get the label until next check-in, the label is harder to work with in Inventory, and it's a little less user-friendly to add/remove devices to the label. However, it has worked well for me, and I hope it could prove useful to others.
"MACHINE.NAME in ([comma separated names])"
If you want this list to persist even if computers are renamed, consider using an intermediate query to find the Machine ID based on name, then use "MACHINE.ID in ([comma separated IDs])" instead of MACHINE.NAME - JasonEgg 8 years ago
Thanks for the post. but i am getting an error every time i execute your code.
Are you sure the switch "-NoNewline" is a proper switch for Out-File?
As I am getting the below run error:
Out-File : A parameter cannot be found that matches parameter name 'NoNewline'.
As far as I am aware PS has nonewline only for write-host, unless i am missing something here? - ICTLicences 7 years ago
[System.IO.File]::WriteAllText($SavePath,"SELECT MACHINE.NAME AS SYSTEM_NAME, SYSTEM_DESCRIPTION, MACHINE.IP, MACHINE.MAC, MACHINE.ID as TOPIC_ID FROM MACHINE WHERE (MACHINE.NAME =""$Machine"")",[System.Text.Encoding]::ASCII)
and
[System.IO.File]::AppendAllText($SavePath,"SELECT MACHINE.NAME AS SYSTEM_NAME, SYSTEM_DESCRIPTION, MACHINE.IP, MACHINE.MAC, MACHINE.ID as TOPIC_ID FROM MACHINE WHERE (",[System.Text.Encoding]::ASCII) - ICTLicences 7 years ago
However, after posting this blog, I found a much simpler way to do this here: http://www.itninja.com/question/how-do-i-populate-the-device-list-in-a-script-by-importing-contents-of-a-csv-file.
Basically, just do a regular smart label with System Name matches regex with computer names separated by a pipe (Ex. MACHINE1|MACHINE2|MACHINE3) - anonymous_129525 7 years ago