导致溢出的Powershell脚本

时间:2017-04-12 15:57:28

标签: sql-server xml powershell

我正在针对SQL实例列表运行以下Powershell脚本以返回实例信息,包括用户和角色。我想使用Powershell来完成这项工作,因为我要整理数据并导入到另一个系统中进行分析。

我创建了以下脚本,该脚本为找到的每个实例创建XML文件输出。这个剧本效果很好(是的,它可能很笨拙而且很糟糕,但是我学习了所以请随意给我一个正确的方向)但是对于其中一个服务器如果有几百个SQL登录,我会在屏幕上显示溢出消息,XML文件未正确关闭,因此我无法将结果导入我的分析系统。

我想要:

关于可能导致溢出的原因的想法。作为参考,崩溃的输出XML大小为2.5MB,在溢出发生之前XML输出中大约有39,000行

[OR]

获得此输出的另一种方法 - CSV是一个选项,但我不知道如何输出这个 - 任何人都可以提供提示吗?

提前谢谢

#Input file is a plain text file with the name of each of the instances listed in it
$InputFile="C:\Tasks\SQL\Permissions\in\Instances.txt"
$OutputFolder="\\networkdrive\sharedfolder\"

Function GetDBUserInfo($Dbase)  
 {  
 if ($dbase.status -eq "Normal")  # ensures the DB is online before checking
    {$users = $Dbase.users | where {$_.login -eq $SQLLogin.name}   # Ignore the account running this as it is assumed to be an admin account on all servers
foreach ($u in $users)  
{  
    if ($u)  
    {   
        $XmlWriter.WriteStartElement("Login")
            $XmlWriter.WriteElementString('DBName', $dbase.name)
            $XmlWriter.WriteElementString('LoginName', $SQLLogin.name) 
            $XmlWriter.WriteStartElement('Login_Roles')
            $DBRoles = $u.enumroles()   
            foreach ($role in $DBRoles) 
            {
                    $XmlWriter.WriteElementString('Role', $Dbase.name)
            } 
            $XmlWriter.WriteEndElement()#Login_Roles
            #Get any explicitly granted permissions
            $XmlWriter.WriteStartElement('Login_Permissions')
                $XmlWriter.WriteElementString('Instance', $svr.name)
                $XmlWriter.WriteElementString('DBName', $dbase.name)
                $XmlWriter.WriteElementString('LoginName', $SQLLogin.name) 
                foreach($perm in $Dbase.EnumObjectPermissions($u.Name))
                {
                    $XmlWriter.WriteElementString('Permissions', $perm.permissionstate.tostring() + " " + $perm.permissiontype.tostring() + " on " + $perm.objectname.tostring() + " in " + $DBase.name.tostring())
                }  
            $XmlWriter.WriteEndElement() #Login_Permissions
        $XMLWriter.WriteEndElement() #Login
    } # Next user in database  
   }  
   #else  
   #Skip to next database.  
 }  
}

#Main portion of script start  
[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null  #ensure we have SQL SMO available

foreach ($SQLsvr in get-content $InputFile)  # read the instance source file to     get instance names
{  
$svr = new-object ("Microsoft.SqlServer.Management.Smo.Server") $SQLsvr  
        #Cycle through each instance and write the instance information to the file

#Output file is base folder for each of the text files (which will be named for the instance)
$OutputFile = $svr.name
$OutputFile = $OutputFolder+$OutputFile.Replace("\", "-")+".xml"

# get an XMLTextWriter to create the XML
$XmlWriter = New-Object System.XMl.XmlTextWriter($OutputFile,$Null)

# choose a pretty formatting:
$xmlWriter.Formatting = 'Indented'
$xmlWriter.Indentation = "4"


# write the header
$xmlWriter.WriteStartDocument()

# set XSL statements
$XLSPropText="type='text/xsl' href='style.xsl'"
$xmlWriter.WriteProcessingInstruction("xml-stylesheet", $XSLPropText)

# create root element "instances" and add some attributes to it
$xmlWriter.WriteStartElement("Root")

$XmlWriter.WriteStartElement("Instance")
$XmlWriter.WriteElementString("SQLInstance", $svr.name)
$XmlWriter.WriteElementString("SQLVersion", $svr.VersionString)
$XmlWriter.WriteElementString("Edition", $svr.Edition)
$XmlWriter.WriteElementString("LoginMode", $svr.loginmode)
$XmlWriter.WriteEndElement #instance

$SQLLogins = $svr.logins  


foreach ($SQLLogin in $SQLLogins)  
{
    #Iterate through each login, writing the details into the login details
    #$XmlWriter.WriteComment("Login Details")
    $xmlWriter.WriteStartElement("Logins")
    $XmlWriter.WriteElementString("InstanceName", $svr.Name)
    $XmlWriter.WriteElementString("LoginName", $SQLLogin.Name)
    $XmlWriter.WriteElementString("LoginType", $SQLLogin.LoginType)
    $XmlWriter.WriteElementString("Created", $SQLLogin.CreateDate)
    $XmlWriter.WriteElementString("DefaultDatabase", $SQLLogin.DefaultDatabase)
    $XmlWriter.WriteElementString("Disabled", $SQLLogin.IsDisabled)

    $SQLRoles = $SQLLogin.ListMembers()
    If ($SQLRoles) 
        { $XmlWriter.WriteElementString("ServerRole", $SQLRoles) }
    else 
        { $XmlWriter.WriteElementString("ServerRole", "Public") }

    If ( $SQLLogin.LoginType -eq "WindowsGroup" ) 
        {   #get individuals in any Windows domain groups
            $XmlWriter.WriteStartElement("WindowsLogins")
            $XmlWriter.WriteElementString("InstanceName", $svr.name)
            $XmlWriter.WriteElementString("Login", $SQLLogin.name)
            try {   
                    $ADGRoupMembers = get-adgroupmember  $SQLLogin.name.Split("\")[1] -Recursive
                    foreach($member in $ADGRoupMembers)
                    { $XmlWriter.WriteElementString("Account", $member.name.tostring() + "(" + $member.SamAccountName.tostring() +")") }
                }
            catch
                {
                #Sometimes there are 'ghost' groups left behind that are no longer in the domain, this highlights those still in SQL
                    $XmlWriter.WriteElementString("Account", "Unable to locate group " + $SQLLogin.name.Split("\")[1] + " in the AD Domain")
                }
            $XmlWriter.WriteEndElement()
            }
    #Check the permissions in the DBs the Login is linked to.
    If ($SQLLogin.EnumDatabaseMappings())  
    {
        $XmlWriter.WriteStartElement('Permissions')
        $XmlWriter.WriteElementString('InstanceName', $svr.name)
        $xmlwriter.WriteElementString('Login', $SQLLogin.name)
        foreach ( $DB in $svr.Databases)   
           {
            try {   
                               GetDBUserInfo($DB)
                }
            catch
                {
                    echo $_.Exception|format-list -force
                }
           } # Next Database  

        $XmlWriter.WriteEndElement()
        }  
        Else  
        {
            $XmlWriter.WriteStartElement('Permissions')
            $XmlWriter.WriteElementString('InstanceName', $svr.name)
            $xmlwriter.WriteElementString('Login', $SQLLogin.name)
            $XmlWriter.WriteElementString('Permissions', 'No Permissions')
            $XmlWriter.WriteEndElement()
        }   
    $xmlWriter.WriteEndElement() #End Logins element
    }
}

# close the "machines" node:
$xmlWriter.WriteEndElement() #root node

# finalize the document:
$xmlWriter.WriteEndDocument()
$xmlWriter.Flush()
$xmlWriter.Close()    

运行时,错误消息为:

OverloadDefinitions
--------------------    
void WriteEndElement()
void WriteEndElement()

没有给出其他错误或消息。该文件确实已写入但不完整。

0 个答案:

没有答案