我有一个PowerShell脚本,一直让我感到烦恼。我终于到了可以获得收藏的地步,但是我收到了一个我无法弄清楚的错误。
function Get-MongoDBCollection {
Param(
$database,
$CollectionName,
$settings = $null, #[MongoDB.Driver.MongoCollectionSetting]
$returnType = [PSOBJECT]
)
$method = $database.GetType().GetMethod('GetCollection')
$gericMethod = $method.MakeGenericMethod($returnType)
$gericMethod.Invoke($database,[object[]]($CollectionName,$settings))
}
$dbName = "MyDatabaseName"
$collectionName = "MyCollectionName"
try {
add-type -path 'C:\Program Files\MongoDB\Drivers\System.Runtime.InteropServices.RuntimeInformation.4.0.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll'
Add-Type -Path "C:\Program Files\MongoDB\Drivers\MongoDB.Bson.2.6.0\lib\net45\MongoDB.Bson.dll"
add-type -path "C:\Program Files\MongoDB\Drivers\DnsClient.1.0.7\lib\net45\DnsClient.dll";
Add-Type -path "C:\Program Files\MongoDB\Drivers\MongoDB.Driver.Core.2.6.0\lib\net45\MongoDb.Driver.Core.dll"
Add-Type -Path "C:\Program Files\MongoDB\Drivers\MongoDB.Driver.2.6.0\lib\net45\MongoDB.Driver.dll"
}
catch {
$_;
$_.Exception.LoaderExceptions
}
$connectionString = "mongodb://localhost:27018";
$mongoClient = new-object MongoDb.Driver.MongoClient($connectionString);
$mongoDatabase = $mongoclient.GetDatabase($dbName)
$mongoDatabase.GetCollection($collectionname)
$collection = Get-MongoDBCollection $mongodatabase "SharePoint" -returnType ([MongoDB.Bson.BsonDocument]);
$datafile = Get-Content -Raw -Path "D:\datafiles\86fba866-77ed-4f40-4637-08d57d2e25b4.json" #`| ConvertFrom-Json
[MongoDB.Bson.BsonDocument] $doc = [MongoDB.Bson.BsonDocument]::Parse($datafile);
$x = $collection.InsertOne($doc)
该脚本获取文件的内容,该文件包含JSON字符串并将其转换为BsonDocument,然后尝试插入它。我收到以下错误。
Argument types do not match
At line:1 char:1
+ $collection.InsertOneAsync($doc)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException
我在这里做错了什么?
答案 0 :(得分:0)
这是一个艰难的饼干!基本上,powershell不会以微不足道的方式支持泛型。它支持它们,但是以复杂且难以理解的方式支持它们!
我在几天前在另一个堆栈溢出中发现了这个片段,但此时无法找到它。开始时这是一个令人不愉快的搜索/跋涉。我希望我可以给予适当信用的原作者的片段如下:
###
# Usage:
# $Collection = Get-MongoDBCollection $database 'collectionName'
# or
# $Collection = Get-MongoDBCollection $database 'collectionName' -returnType ([MongoDB.Bson.BsonDocument])
function Get-MongoDBCollection {
Param(
$database,
$CollectionName,
$settings = $null, #[MongoDB.Driver.MongoCollectionSetting]
$returnType = [PSOBJECT]
)
$method = $database.GetType().GetMethod('GetCollection')
$gericMethod = $method.MakeGenericMethod($returnType)
$gericMethod.Invoke($database,[object[]]($CollectionName,$settings))
}
以下是我在下面的完整上下文用法。我还必须自己加载DnsClient.dll依赖项。在整个过程中,通常情况下,powershell模块无法提供有用的错误。
PS:这是业余的powershell,只使用.ps因为我需要连接Office365!没有最佳实践的承诺!#########
# Globals
##
$mongoDbDriverPath = "Z:\Work\mb-rule-watch\lib\net45"
$dbName = "mbRules"
$collectionName = "Mailboxes"
#########
# Load o365 credentials/modules
##
Import-Module MsOnline
if( ! $credential ){
Write-Host "Requesting Credentials - Use o365 Admin Account"
$credential = Get-Credential
Connect-MsolService -Credential $credential
}
# Prep remote session connection
if( ! $session ){
$session = New-PSSession `
-ConfigurationName Microsoft.Exchange `
-ConnectionUri https://outlook.office365.com/powershell-liveid/ `
-Credential $credential `
-Authentication Basic `
-AllowRedirection
# import commands from Microsoft Exchange Server shell
Import-PSSession $session
}
###########
# Functions
##
###
# Usage:
# $Collection = Get-MongoDBCollection $database 'collectionName'
# or
# $Collection = Get-MongoDBCollection $database 'collectionName' -returnType ([MongoDB.Bson.BsonDocument])
function Get-MongoDBCollection {
Param(
$database,
$CollectionName,
$settings = $null, #[MongoDB.Driver.MongoCollectionSetting]
$returnType = [PSOBJECT]
)
$method = $database.GetType().GetMethod('GetCollection')
$gericMethod = $method.MakeGenericMethod($returnType)
$gericMethod.Invoke($database,[object[]]($CollectionName,$settings))
}
###########
# MAIN
##
try
{
# Load mongo driver
Add-Type -Path "$($mongoDbDriverPath)\DnsClient.dll"
Add-Type -Path "$($mongoDbDriverPath)\MongoDB.Bson.dll"
Add-Type -Path "$($mongoDbDriverPath)\MongoDB.Driver.Core.dll"
Add-Type -Path "$($mongoDbDriverPath)\MongoDB.Driver.dll"
# Connect to mongo
$client = new-object -TypeName MongoDB.Driver.MongoClient -ArgumentList "mongodb://localhost"
# Get DB handle
[MongoDB.Driver.IMongoDatabase] $db = $client.GetDatabase( $dbName );
# Aquire Collection handle with brute force generic hacks Via a PS god on stackoverflow.
$collection = Get-MongoDBCollection $db $collectionName -returnType ([MongoDB.Bson.BsonDocument])
#foreach( $mbx in $( Get-Mailbox -ResultSize Unlimited -identity example_user_id ) ){
foreach( $mbx in $( Get-Mailbox -ResultSize Unlimited ) ){
$identityStr = $mbx.identity
$rules = Get-InboxRule -Mailbox $identityStr
# convert some huge ints (>Mongo Int64) to strings
foreach( $rule in $rules ){
$rule.RuleIdentity = "" + $rule.RuleIdentity + ""
}
# Json Stringify
$rules_json = ConvertTo-Json $rules
# If the mailbox had rules
if( $rules_json ){
write-host( "Inserting rules for: " + $identityStr )
# Cache results to FS this time.
echo $rules_json > var\rules\$identityStr.rules.json
try{
# Type convert/parse our json string
$document = new-object -TypeName MongoDB.Bson.BsonDocument
$document = [MongoDb.Bson.BsonDocument]::Parse( '{ "_username":"' + $identityStr + '","rules": ' + $rules_json + '}' );
# Insert the JSON document
$collection.InsertOne( $document )
} catch {
Write-Host "JSON parse or mongo insert failure"
foreach( $x IN $_.Exception ){
foreach( $msg IN $x ){
Write-Error $msg
}
}
}
}
}
}
catch
{
Write-Host "Script errors occured"
if( $_.Exception.LoaderExceptions ){
Write-Host "!!Dependency Loads Failed!!"
foreach( $msg IN $_.Exception.LoaderExceptions ){
Write-Error $msg
}
} else {
foreach( $x IN $_.Exception ){
foreach( $msg IN $x ){
Write-Error $msg
}
}
}
}