I am trying to write a script to automate VDI deployment and I have everything working except for setting the MAC addresses correctly. I am not new to writing scripts but I will say this is the most complicated yet.
I am trying to create an array with the MAC addresses and then run a foreach. But I am not sure how to make it use each object in the array when the foreach loops.
Please see a piece of the script below:
$array = #('00155d9df9b8','00155d9df921')
$i = 1
$vminstances = Read-Host -Prompt 'How many VMs?'
for ($i=1; $i -le $vminstances; $i++)
The foreach would run through names of VMs and rename accordingly. But I can't simply use a MAC address with increments of 1 each loop, as they are using different characters, not just numbers.
How can I include each object stored in the array in each loop?
Perhaps it was never designed to work like this and maybe I need to rethink this. Please could somebody advise?
I would greatly appreciate assistance.
Powershell makes arrays really easy to work with and you don't need to do that style of a for loop. Simply use your array in a foreach loop and then you have a variable to work with that works more like a cursor than having to read from the array using indexes...
$array = #('00155d9df9b8','00155d9df921')
foreach($mac in $array)
{
Write-Output $mac
}
Related
I have a issue where I want to create a function for getting certain information on computers through a list.txt of objects in our environment. Foreach $Computer in $Computers. Pipe it into an Array with variables for each and do Get-Ciminstance on $Computer. So far every information is working when resulting the $ArrayResult as in the image below. But as soon as I try sorting Microsoft Certificates in the $ArrayResult everything displays very 'odd'...
$ArrayOutput
As you see it works great in console. But the output of my array is being displayed as {#{Subject=CN etc.... } instead of just a single output like 'CN=Root Agency'. And when being exported to a .CSV file also displays random characters.
Solution
-expandproperty for showing the array without {#{ output } swirly marks.
and
-last 1. Since an array variable (I think?) cannot display more than one property when being exported to CSV column.
I have two data arrays:
$arrnames=('a','b','c')
$arrtypes=('x','y','z')
and I have a lookup array:
$arrlookup=('y','z')
I need to return the elements in $arrnames where the matching element in $arrtypes is contained in $arrlookup. I've been playing with foreach looping over $arrnames and looking at the same element in $arrtypes by index but it's getting sloppy and I know there has to be a better way.
I've seen some similar questions, but not anything that strikes me as specifically answering this problem. Being a Powershell very newbie I'm still learning how to adapt examples to my needs. Any help is greatly appreciated.
My code (technique used as applied to above example - actual code is using complex arrays derived from an XML file and has a lot of debugging code so copy/paste is impractical)
foreach ($a in $arrnames) {
$t=$arrtypes[$arrnames.IndexOf($a)]
if ($arrlookup.Contains($t)) {
$arrresult+=$a
}
)
$arrresult should contain the members of $arrnames that have a type (from $arrtypes) that is in $arrlookup.
Is there a way to use object methods, filtering and the pipeline to simply extract the elements without a foreach loop
Edit - here's the actual code that creates the actual arrays - $builds is an XML document:
$names=$builds.builds.project.name
$types=$builds.builds.project.type
The lookup table is known:
$FXCopTypes=#('batch','component','web')
The XML file I also have control over, but I don't see any way to simplify it more than implementing the hash table code but with the above arrays.
I think you need to change you input inorder to be able to do anything different here. What you are asking for is $arrnames and $arrtypes to really be a hashtable. That way you can access the values using keys.
As it stands I would do this to create the hashtable. The second loop shows how to return each matching value.
$hash = #{}
for($index = 0; $index -lt $arrtypes.Count; $index++){
$hash.($arrtypes[$index]) = $arrnames[$index]
}
$arrresult = $arrlookup | ForEach-Object{
$hash[$_]
}
This would return
b
c
If you could get your input to create that hash table then it reduces the need to rebuild it. Also if you know the lookup before hand as well you can filter it then and just have the output you want.
I cannot seem to find anything about using the values of one property of an object in a foreach loop (without having the entire object placed into the loop).
I first create a function called UFGet-Servers that uses Get-ADComputer and returns the names of the servers in a specific OU in my environment and places them in an array. That's great, except that when I use the array in a foreach loop, each object that it grabs has #[Name=serverName] in it, which I cannot use in any useful manner. The following pseudo-code is an abbreviated example:
foreach($Computer in $ComputerNames){do code... code is adding the server name into a UNC path such as "\\$Computer\C$\"}
The problem with the above is that you can't add the whole object to a path -- it ends up looking like "\#[Name=serverNameHere]\C$\" which totally bombs out. How do I get rid of the "#[property=" part, and simply use the value as the $Computer in the loop?
What really weirds me out is that I can't find a straightforward article on this anywhere... would have thought everyone and their mom would have wanted to do something like this.
So, your issue isn't with ForEach loops, it is with string formatting. There are two ways that I know of to take care of what you need. First is going to be string formatting, which allows you to use {0}m {1} and so on to inject values into a string, providing that you follow the string with -f and a list of said values. Such as:
ForEach($Computer in $ComputerNames){
"The Server Path is \\{0}\Share$" -f $Computer.Name
}
The second way is a sub-expression (I'm sure somebody will correct me if I used the wrong term there). This one involves enclosing the variable and desired property (or a function, or whatever) inside $(). This will evaluate whatever is inside the parenthesis before evaluating the string. See my example:
ForEach($Computer in $ComputerNames){
"The Server Path is \\$($Computer.name)\Share$"
}
I've developed a custom .tpl.php file for my View and in the past it has worked. Suddenly, while working on my Macbook using MAMP, Drupal decided that the $views->rows needs to be output as a String type and not an array. I've searched online and here for an answer but can't find one. I'm not doing any pre-process or views_render hooks in my template.php file for the theme. Does anyone have any ideas or have seen this before?
Thanks
After going through the Views module code, I couldn't find a _render hook that I would alter to cause the $rows to go back to an Array type. I did go through the modules/views/theme/views-view.tpl.php
So I replaced most of the code in my own template with the views-view.tpl.php code, as well as replacing the database with a previous version so I could start completely over. Turns out the issue was with my template file not outputting the exposed filters and such, as well as Views using
print $rows
instead of using $rows as an array. Seems like whatever version of Views I'm using uses the $rows variable as a String. So I've put in a %SPLIT% string in the Rewrite Results box so that I can do a PHP preg_split, feed that resulting array into my function to generate what I need, then do a preg_replace to get rid of the %SPLIT% strings in $rows. The result looked like what I had.
So, bottom line, looks like Unformatted Fields in Views now outputs $rows as a String variable instead of an array.
I also discovered this when trying to theme a certain row differently if a condition was met. Most things can be done in the Views UI but I couldn't figure out this one like that. I was finally able to do this with yourtheme_preprocess_views_view_unformatted(&$vars) in my template.php file. $rows seemed to still behave like an array there (although it went back to being a string later).
function yourtheme_preprocess_views_view_unformatted(&$vars) {
if ($vars['view']->name == "name_of_view") {
$rows = $vars['rows'];
$newRows = array();
foreach ($rows as $r) {
$test = strpos($r, "string_i_looked_for");
if ($test) {
$newRows[] = "<hr>$r"; // I needed to put in a divider if the condition was met.
}
else {
$newRows[] = $r;
}
}
$vars['rows'] = $newRows; // So that the array of new rows is what will be sent along.
}
}
My actual problem required the divider only in the first instance of the test, so I also used a counter, but I think the example above gives the idea.
Really simple perl question, but confusing me greatly.
foreach $val (#{$obj->something()}) {
# this works
}
#array = $obj->something();
foreach $val (#array) {
# this does not
}
What do i need to do to make the second work (i.e: assign the array seperately), i've used the first form a fair bit but dont really understand what it does differently.
Probably:
#array = #{$obj->something()};
From the first example, it looks like $obj->something() returns an array reference, you'll need to dereference it.
Also, you should really use strict; and use warnings;, and declare your variables like
my #array = #{$obj->something()};
foreach my $val (#array) {
# this does not
}
This will make it much easier to find mistakes (although probably not this one), even in a three line script.