Setting multiple properties at once in Powershell - syntax

Is there a shorter way to set multiple properties to the same value in Powershell in one command than this?
Example:
(gi "c:\test.txt").LastWriteTime = (gi "c:\test.txt").LastAccessTime = (gi "c:\test.txt").CreationTime = Get-date
I'm just curious if there is a way to shorten this syntax.

"CreationTime","LastWriteTime","LastAccessTime" |% {(gi test.txt).$_ = (get-date)}

I've used a slightly modified version of Mjolinor's answer to solve a problem I had of incorrect date on files that had just been downloaded from a remote source. I modified the code to make it cleaner to understand in case I have to come back to in the future (changed the short hand to full command names).
# Correct Access/Create/Write times on transferred files
ForEach( $File in $TransferList ) {
#("CreationTime","LastAccessTime","LastWriteTime") | ForEach {
$(Get-Item $File.Name).$_ = $File.Date
}
}

Related

How to glob and check multiple files in InstallBuilder?

I'm making installer program using VMware InstallBuilder (previously named Bitrock InstallBuilder), and need to ensure the non-existence of some files in target directory. Here I describe its logic in Perl fake code:
sub validate_target_dir
{
my $target_dir = shift;
# find all candidate check files
foreach my $file ( glob( "$target_dir/*_vol0.dat" ) )
{
my $fname = basename($file);
# fail if has any data file other than myproduct
if ($fname ne "myproduct_vol0.dat") { return 0; }
}
return 1;
}
However I don't know how to implement similar logic in InstallBuilder, as its findFile action don't return multiple matching files (only the first one).
At current, I find a somewhat twisted way to do it: implement the function in a shell script. InstallBuilder allows you to unpack contents programmatically, so I can pack the script into the installer package and unpack&run it at needed time.
I still seek if there's possible way that purely implemented by InstallBuilder itself.

How do I add multiple attachments to Powershell email script

I am running a script to listen for new files in a specific folder. When it finds a new file I want email that file, and another file that I'm explicitly defining. here's a bit of code :
$Report = "C:\somefolder\somefile.xml"
$AnotherReport = "C:\somefolder\someotherfile.xml"
And a bit later I want to do something like this
Send-MailMessage -Attachments $Report,$AnotherReport
I want to add more than one attachment from different locations. What is the proper syntax to do that?
I have not tested but you can try like this
#Converts to array
$Report = #("C:\somefolder\somefile.xml")
$AnotherReport = "C:\somefolder\someotherfile.xml"
$Report += $AnotherReport
Send-MailMessage -Attachments $Report

Sitecore item multilistfield XPATH builder

I'm trying to count with XPATH Builder in Sitecore, the number of items which have more than 5 values in a multilist field.
I cannot count the number of "|" from raw values, so I can say I am stuck.
Any info will be helpful.
Thank you.
It's been a long time since I used XPath in Sitecore - so I may have forgotten something important - but:
Sadly, I don't think this is possible. XPath Builder doesn't really run proper XPath. It understands a subset of things that would evaluate correctly in a full XPath parser.
One of the things it can't do (on the v8-initial-release instance I have to hand) is be able to process XPath that returns things that are not Sitecore Items. A query like count(/sitecore/content/*) should return a number - but if you try to run that using either the Sitecore Query syntax, or the XPath syntax options you get an error:
If you could run such a query, then your answer would be based on an expression like this, to perform the count of GUIDs referenced by a specific field:
string-length( translate(/yourNodePath/#yourFieldName, "abcdefg1234567890{}-", "") ) + 1
(Typed from memory, as I can't run a test - so may not be entirely correct)
The translate() function replaces any character in the first string with the relevant character in the second. Hence (if I've typed it correctly) that expression should remove all your GUIDs and just leave the pipe-separator characters. Hence one plus the length of the remaining string is your answer for each Item you need to process.
But, as I say, I don't think you can actually run that from Query Builder...
These days, people tend to use Sitecore PowerShell Extensions to write ad-hoc queries like this. It's much more flexible and powerful - so if you can use that, I'd recommend it.
Edited to add: This question got a bit stuck in my head - so if you are able to use PowerShell, here's how you might do it:
Assuming you have declared where you're searching, what MultiList field you're querying, and what number of selections Items must exceed:
$root = "/sitecore/content/Root"
$field = "MultiListField"
$targetNumber = 3
then the "easy to read" code might look like this:
foreach($item in Get-ChildItem $root)
{
$currentField = Get-ItemField $item -ReturnType Field -Name $field
if($currentField)
{
$count = $currentField.Value.Split('|').Count
if($count -gt $targetNumber)
{
$item.Paths.Path
}
}
}
It iterates the children of the root item you specified, and gets the contents of your field. If that field name had a value, it then splits that into GUIDs and counts them. If the result of that count is greater than your threshold it returns the item's URI.
You can get the same answer out of a (harder to read) one-liner, which would look something like:
Get-ChildItem $root | Select-Object Paths, #{ Name="FieldCount"; Expression={ Get-ItemField $_ -ReturnType Field -Name $field | % { $_.Value.Split('|').Count } } } | Where-Object { $_.FieldCount -gt $targetNumber } | % { $_.Paths.Path }
(Not sure if that's the best way to write that - I'm no expert at PowerShell syntax - but it gives the same results as far as I can see)

How to get the details of a file on Windows

If you open the properties of a file in Windows, there usually is a Details tab. I want to access the information on this tab, but I don't know how.
Is there a module for it? Does someone has a code sniplet?
I tried to work with Win32::File's GetAttributes, but these are not the attributes I was looking for.
use Win32::OLE;
my $objShell = Win32::OLE->new("Shell.Application") or die;
my $objFolder = $objShell->NameSpace($myDir) or die;
my $objFile = $objFolder->ParseName($fileName) or die;
while ( $i <= 34 )
{
my $propertyName = $objFolder->GetDetailsOf($fileName,$i);
my $propertyValue = $objFolder->GetDetailsOf($objFile,$i);
print "$i -- $propertyName -- $propertyValue\n";
$i++;
}
You can instantiate a COM "Shell.Application" object. It exposes a .NameSpace(folder) method that returns a reference to the name space of the indicated folder, which holds the information you need. The retrieved instance holds a Items collection with references to each of the files in the folder, and a .GetDetailsOf(file,property) to retrieve each of the values seen in the details tab and explorer columns.
Sorry i have no idea of perl, so i can not include any working code.

php xpath query on and xpath result

Can I use an xpath query on a result already obtained using xpath?
In most hosting languages/environments (like XSLT, XQuery, DOM) you can. Don't know about PHP, but it would be strange if it doesn't allow this.
Of course, the result of the first query must be a node-set, in order for a future "/" operator to be possible/allowed/successful on it.
I have done it in PHP/SimpleXML. The thing that I didn't understand at first is that you're still dealing with the full SimpleXML object, so if you start with "/nodename", you're operating on root. If you start with "nodename" you are starting at the beginning of the result node. Here's my example:
$parsed=simplexml_load_string($XML);
$s = '/ItemSearchResponse/Items/Item';
$items = $parsed->xpath($s);
foreach($items as $item)
{
$s = 'ItemAttributes/Feature';
$features[]=$item->xpath($s);
$s = 'ASIN';
$asins[]=$item->xpath($s);
$s = 'ImageSets/ImageSet[#Category="primary"]';
$primary_img_set=$item->xpath($s);
$s = 'MediumImage/URL';
$medium_image_url[] = $primary_img_set[0]->xpath($s);
}
In PHP, for example, you can run a query with a context, i.e. a given node. So if you have got a DOMNodeList as a result of the first query you can do things like this:
$query1 = '//p';
$query2 = './a'; // do not forget the dot
$node = $xpath->query($query1)->item(0);
$result = $xpath->query($query2, $node);
Of course this is a silly example because it could have been done just in one shot with the correct XPath experssion but I believe it illustrates your question.

Resources