I pieced together a pipeline that returns a list of files and their paths if said files match prescribed patterns:
Param ($dropDir)
$MatchingScripts = Get-ChildItem $dropDir\*.sql -Recurse
| Select-String -pattern \*ONEFISH\*,\*TWOFISH\*,\*REDFISH\*
| group path
| Foreach-Object {$_.Name}
| Out-File D:\logging\scrubfiles.log
return $MatchingScripts
So there's one param in there where I feed in the dynamically-named drop path every time and search down that path. The goal then is to return $MatchingScripts array to the build template and throw the array into a ForEach<string> loop that will InvokeProcess on a custom tool which will scrub each \path\file\ and replace said token value patterns.
Problem: I can't get that array from PowerShell fed back to the team build. I've tried containing the script in a .ps1 along with a closing return $MatchingScripts ...but nothing is reaching the pre-defined IEnumerable<String> by the same name 'MatchingScripts' in the build template.
I'm still trying to make the TFSBuildExtensions InvokePowerShellCommand activity to do this for me, as well, but the problem there is a conversion of types that have to be overcome (PSOBject to Array of Strings).
They key bit is that tool I have to send this array through needs to consist of strings.
If it were me I'd just loop through and call your custom tool directly from PowerShell, rather than trying to pass data back to WF and doing it from there.
Here's the work-around we used to return value:
Since what we piped out to log was clean (just files & paths), we read the log back into an array of strings via the Assign activity using a VB expression...
MatchingScripts = File.ReadAllLines("D:\logging\scrubfiles_" + BuildDetail.BuildNumber.ToString() + ".txt")
There's a little concatenation there because we later chose to individualize the each log according to the 'build' it ran under. Anyway, it worked a treat!
Moral of the story: understand that if you want to return ANYTHING other than an integer value from PowerShell/InvokeProcess, be prepared to write/find a custom activity or come up with some other work-around that can feed directly back into Workflow.
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 some ruby code from my Ruby on Rails project.
I am formatting some data so I am calling attributes.extract! to get the fields I need from my model.
I noticed recently that every now and then the data wouldn't get extracted as expected. I realized that I needed a splat operator. But it is strange because I do notice that sometimes when the method is called in my Rails project it will sometimes extract the data without the use of the splat operator. But when I run the code from my Rails console it never extracts the data unless I add the splat operator.
Here is the code in question
# in a service file, let's call it service.rb
def self.format_user_home_address_data(user)
# This doesn't work in the console but sometimes works when run in my Rails project
home_address_data = user.attributes.extract!(User::HOME_ADDRESS_FIELDS)
home_address_data[:address_type] = "home"
home_address_data
end
# at the end this method will sometimes return { address_type: "home" } or
# sometimes it'll actually return the extracted attributes as expected
HOME_ADDRESS_FIELDS is just an array with the values ["address_line_1", "city", "state", "zip"]
Anyway I know that to get it to run correctly I need to do this
home_address_data = user.attributes.extract!(*User::HOME_ADDRESS_FIELDS)
But does anyone know why I was able to get away without adding the splat operator for so long? Is there some Ruby on Rails magic that is only sometimes happening? What's the deal?
Well, let's check it out. There is no any magic behind attributes.extract! in the end. Here is an actual implementation of this method from Rails source code:
def extract!(*keys)
keys.each_with_object(self.class.new) { |key, result|
result[key] = delete(key) if has_key?(key)
}
end
Link: click. As you can see, it creates new hash, goes over the keys one by one and moves value from self to this new array. So, if you give an Array argument to this method then key in the block will be an Array as well. So, it won't be found. So, no way it may work for array argument. The only one possibility is that something else is passed instead of User::HOME_ADDRESS_FIELDS.
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.
There's a webpage I'm trying to test that has multiple textboxes. I've gotten to the point where I can retrieve all the values in every textbox and store them into an array, but I'm stuck on how to type those same values into the textboxes again.
Here's what I have so far in Selenium:
Larger view: http://i.stack.imgur.com/rb93k.png
The stored variable 'count' is simply the number of rows in the table, and isn't causing a problem. The part I've circled in red is where the problem comes in.
When I run this test, instead of typing the value stored in the array at that index, it simply types:
This continues all the way until the end.
The variable 'i' is properly inserted, but for some reason instead of grabbing that value, it simply types it into the textbox.
Does anyone know how I can get the correct value in the array?
Below is the problematic line:
type | javascript{this.browserbot.getUserWindow().getTestingHooks('TextBoxValue_' + storedVars['i'])} | ${textBoxArray[${i}]} |
i'm using Selenium library through Robot Tests Framework. I'm not using any IDE, just using HTML to make test cases and defining new keywords.
When ever i want to access a list variable item, i just use the following sintaxe
#{list_variable_name}[0]
note that ${variable_name} is to access a single value variable or the reference to the list variable. If we want to access a list item we need to use # instead of $.
If i understand your situation right,
#{textBoxArray}[${i}] should work for you.
Try also
${textBoxArray}[${i}] because it seems that your are simply misplaycing the last }.
More details at
http://robotframework.googlecode.com/svn/tags/robotframework-2.5.4/doc/userguide/RobotFrameworkUserGuide.html#list-variables
I think you need to replace your circled reference to ${textBoxArray[${i}] with
javascript{storedVars['textBoxArray['+storedVars['j']+']']}
Read this blog post for more information, especially the section about 'Setting and getting variables'.
Quoting from the article, consider
store | 10 | x
This obviously sets x=10. There are a couple of ways to reference it:
${x} or storedVars['x']. They're not the same.
In particular
You can't assign anything to ${x}.
You can insert one more command before your problematic line:
getEval | storedVars['text'] = storedVars['textBoxArray'][storedVars['i']];
And change problematic line to:
type | javascript{this.browserbot.getUserWindow().getTestingHooks('TextBoxValue_' + storedVars['i'])} | ${text}
Also it will be probably helpful to declare your array in the beginning of the test:
storeEval | new Array() | textBoxArray