AFAIK, you cannot.
The only way (which I know) to get the values of the identification field is to use either SCOPE_IDENTITY() when inserting row by row; or using the OUTPUT approach when inserting the entire set.
The “simplest” approach would probably be that you would SqlBulkCopy the records in the table and then return them again. The problem may be that it would be difficult to correctly (and quickly) retrieve these lines from the server again. (for example, it would be pretty ugly (and slow) to have a WHERE with IN (guid1, guid2, .., guid999998, guid999999) =)
I assume that performance is a problem here since you are already using SqlBulkCopy, so I suggest moving on to the OUTPUT approach, in which case you will first need a staging table for SqlBulkCopy of your records. the table should include some kind of batch identifier (GUID?), allowing several passes to work side by side. You will need a stored procedure for the INSERT <table> OUTPUT inserted.* SELECT data from the staging table to the actual destination table, and also clear the staging table again. The returend recordset from the specified procedure will then correspond 1: 1 to the original data set, which is responsible for filling the intermediate table, but, of course, you should not rely on its order. In other words: your next task is to map the returned Identity fields to the source records in your application.
Thinking about this, I would say that in all cases - except for the line by line approach and SCOPY_IDENTITY (), which will be slow with the dog - you will need (or add) a “key” to your data in order to associate the generated identifier with source data = /
source share