-2

I am running a script in powershell in multiple threads (multiple shells), and I'm finding that its possible for the NewGuid powershell function to generate values in powershell 7 that are not actually unique when run at the same time.

"${env:TEMP}\some_unique_file_$([guid]::NewGuid()).json"

The above can produce a conflict when I'd like each string here to be unique. Is there something missing or is this a bug? It's almost as if PID is not considered when generating a GUID.

for further context, its also possible because its defined as a parameter default, that this is causing the issue:

param (
    [Parameter(Mandatory = $false)] [string]$houdiniEnvFile = "${env:TEMP}\some_unique_file_$([guid]::NewGuid()).json"
)
openCivilisation
  • 796
  • 1
  • 8
  • 25
  • 3
    Without seeing your code is impossible to tell whats wrong. Certainly, no such thing as a duplicate GUID – Santiago Squarzon Apr 19 '23 at 04:58
  • 3
    [While the probability that a UUID will be duplicated is not zero, it is generally considered close enough to zero to be negligible](https://en.wikipedia.org/wiki/Universally_unique_identifier). Without more details (as a collision rate), I tend to believe what @Santiago implies: you probably doing something wrong (as your expression should at least be quoted). Anyways, you might simply use the [`New-TemporaryFile`](https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/new-temporaryfile) cmdlet for what you trying to do. – iRon Apr 19 '23 at 06:57
  • You need to surround the string with double-quotes and also expand the `.Guid` property: `"${env:TEMP}\some_unique_file_$([guid]::NewGuid().Guid).json"` – Theo Apr 19 '23 at 11:51
  • 1
    @Theo, explicitly referencing the `.Guid` property is _not_ needed in a string-interpolation context, given that `.ToString()` is implicitly called when stringifying an object; try `"$([guid]::NewGuid())"`. Also, if the expression is used _as a command argument_, double-quoting - while advisable - isn't strictly necessary. I think we need more information to find the true cause of the problem. – mklement0 Apr 19 '23 at 13:28
  • @iRon the New-Temporary file command is excellent, thankyou. however I'm interested in getting a shared ID for a number of unique directories and files eventually. – openCivilisation Apr 21 '23 at 02:49
  • 1
    Before coming with a possible solution, it is imparitive to understand what is happening here first. In my believing you need to create so many files from all the sides to be able create a guid collision that it is more likely that you creating a kind of [Denial-of-service (DoS) attack](https://en.wikipedia.org/wiki/Denial-of-service_attack) on the concerned file server. So how did you determine it is a guid conflict, do you get a specific error? Did you capture the conserned guid/filename to prove it is conflict?. Does it really exist already? – iRon Apr 21 '23 at 06:05
  • Hello @iRon, when I checked the logs for unique files being produced I could see sometimes each file was the same. – openCivilisation Apr 22 '23 at 02:58
  • 1
    If you really want to investigate the (high?) rate of of collisions, please [add these details to thre question](https://stackoverflow.com/posts/76050850/edit): when was the guid generated? (afaik, as the is a time component in the guid you can only create a collision at exactly the same time), examples of the collided path/guid. Rate: how often does the collision happen? A ***complete*** [mcve] to be able investigate and reproduce the initial suggested issue. – iRon Apr 22 '23 at 06:46
  • 1
    Btw the loosely definion `"${env:TEMP}\some_unique_file_$([guid]::NewGuid()).json"` already shows a weird train of thought. What does `some_unique_file_` represent? Why not just a verbatim (or no) prefix? (knowing that the `guid` should already be unique.) In other words, you appearently not giving us the full story that proves you really encountered a guid collision. – iRon Apr 22 '23 at 08:06

1 Answers1

-3

Theo is right. You have to expand the property Guid. NewGuid() creates an object with a single property. And to get to the value, this single property has to be expanded.

That will look like this:

${env:TEMP}\some_unique_file_$([guid]::NewGuid().Guid).json

Another possible approach is:

${env:TEMP}\some_unique_file_$((New-Guid).Guid).json

It is as fast, but maybe a little bit easier on the eyes ;)

  • Explicitly referencing the `.Guid` property is _not_ needed in a string-interpolation context, given that `.ToString()` is implicitly called when stringifying an object; try `"$([guid]::NewGuid())"` or `"$(New-Guid)"` - in outcome your commands are equivalent to the command in the question. – mklement0 Apr 19 '23 at 13:27
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Apr 23 '23 at 09:40