【运维】PowerShell编程 目录文件相关方法的封装与案例详解

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 本文实现一个目录管理类,归纳了 Powershell 中常用的文件路径方法。这些方法可以迅速方便的用于 Powershell 编写大型运维脚本中。以简单使用为目的封装常用目录文件操作。完成源代码在作者的github上可以找到。

PowerShell 目录文件管理


目录文件相关方法的封装与案例详解

李俊才 的个人博客https://blog.csdn.net/qq_28550263?type=blog

已入驻阿里云

邮箱 :291148484@163.com
本文地址
- https://developer.aliyun.com/article/
- https://blog.csdn.net/qq_28550263/article/details/124378032

本文通过以一个 Path 类,归纳了 Powershell 中常用的文件路径方法。这些方法可以迅速方便的用于 Powershell 编写大型运维脚本中。


目 录


1. 获取绝对路径

2. 文件名

3. 获取盘符

4. 当前系统临时目录

5. 上级路径

6. 文件或者目录是否实际存在

7. 获取相对路径

8. 获取目录的当前子项目

9. 递归获取目录的所有子孙项目

10. 在指定目录下筛选文件

11. 在指定目录下筛选目录

12. 获取文件或者目录的修改时间

13. 判断指定路径是否实际是一个文件夹

14. 判断指定路径是否实际是一个文件

15. 判断文件时间是否早于某个值

16. 判断目录是否为空

17. 判断某个路径值是否为绝对路径

18. 获取目录的属性描述符

19. 判 断是否包含某个属性描述符

20. 计算文件或目录的大小

21. 连结多个路径

22. 拆分路径

23. 创建目录

24. Path 环境变量相关方法

25. 删除路径对应的项目

附录1: Path类代码

附录2: 脚本位置


1. 获取绝对路径

static [string]abspath([string]$path){
    <#
    Return absolute path
    Params
    ======
    - $path [string] Path of file.
    #>
    return Resolve-Path -Path $path; 
}

如图:

2. 文件名

static [string]basename([string]$path){
    <#
    Returns the file name from the absolute path value represented by a string.
    Params
    ======
    - $path [string] The absolute path of the file.
    - $extension [bool] Whether to remove the extension.
    #>
    return  [System.IO.Path]::GetFileName($path)
}
static [string]basename([string]$path,[bool]$extension=$True){
    if($extension){
        return  [System.IO.Path]::GetFileName($path)
    }
    else{
        return [System.IO.Path]::GetFileNameWithoutExtension($path)
    }
}

如图:

3. 获取盘符

static [string]rootname([string]$path){
    <# Return root directory information #>
    return [System.IO.Path]::GetPathRoot($path)
}

【例如】:

4. 当前系统临时目录

static [string]get_temp_path(){
    <# Returns the path of the current system temporary directory. #>
    return [System.IO.Path]::GetTempPath()
}

【例如】:

5. 上级路径

5.1 获取文件所在目录名(上级目录名)

static [string]get_dirname([string]$path){
    <#
    Returns the name of the folder where the file is located.
    Params
    ======
    - $path [string] Represents the absolute path of a file or folder.
    #>
    return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
}
static [string]get_dirname([string]$path, [bool]$absolute=$True){
    if($absolute){
        return [System.IO.Path]::GetDirectoryName($path)
    }
    else{
        return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
    }
}

【例如】:

备注:

这里图片调用的是之前的版本的方法名,现在已经改名为 get_dirname ,只要替换方法名效果一样,只是没有重新截图了。

5.2 获取文件所在目录名(上级绝对路径)

static [string]get_dirpath([string]$path){
    <#
    Returns the absolute path of the parent folder.
    Params
    ======
    - $path [string] Represents the absolute path of a file or folder.
    #>
    return [System.IO.Path]::GetDirectoryName($path)
}

6. 判断文件或者目录是否实际存在

static [bool] exists([string]$path){
    <#
    Determine whether the specified file or directory exists.
    Params
    ======
    - $path [string] The path value represented by a string.
    Returns
    =======
    - $True  exist.
    - $False non-existent.
    #>
    return Test-Path -Path $path
}

例如:

7. 获取相对路径

static [string]relpath([string]$relativeTo, [string]$path){
    <#
    Returns the relative path from one path to another.
    Params
    ======
    - $relativeTo [string] The source path relative to the result. This path is always treated as a directory.
    - $path [string] Target path.
    Returns
    =======
    [string] Relative path, or path if the paths do not share the same root.
    Exceptions
    ==========
    - [ArgumentNullException] The value of $relativeTo or $path is null。
    - [ArgumentException] $relativeTo or $path is actually null.
    #>
    return [System.IO.Path]::GetRelativePath($relativeTo, $path)
}

【例如】:

8. 获取目录的当前子项目

static [string[]] get_items([string]$path){
    <#
    Get all subprojects in the specified directory. 
    Params
    ======
    - $path [string] The path value represented by a string.
    - $sift [string] Optional, used to indicate the filtered content.
        * When the parameter value is' file', only the absolute path of 
        the files in it will be returned.
        * When the parameter value is' folder', the absolute path of the 
        directory (folder) in it is returned.
    Notes
    =====
        This method only gets the current level of subdirectories, while 
        the folders containing subdirectories will not be traversed.
        If you need to recursively obtain all descendants directories, 
        you should consider using `get_descendants()` method instead.
    #>
    $item_obj = Get-ChildItem $path |  Sort-Object
    $ary = [ArrayList]::new()
    foreach ($item in $item_obj){
        $ary.Add($item.ToString())
    }
    return $ary
}
static [string[]] get_items([string]$path, [string]$sift){
    if($sift -eq 'file'){
        $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
        $ary = [ArrayList]::new()
        foreach ($item in $files){
            $ary.Add($item.ToString())
        }
        return $ary
    }elseif ($sift -eq 'folder') {
        $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
        $ary = [ArrayList]::new()
        foreach ($item in $folders){
            $ary.Add($item.ToString())
        }
        return $ary
    }else{
        $item_obj = Get-ChildItem $path |  Sort-Object
        $ary = [ArrayList]::new()
        foreach ($item in $item_obj){
            $ary.Add($item.ToString())
        }
        return $ary
    }
}

【例如】:

其中:

  • 由于该目录中没有直接子项目为文件,因此当指定第二个参数为file时,结果为空;
  • 指定第二个参数为folder和不指定第二个参数的效果完全一致。

9. 递归获取目录的所有子孙项目

static [string[]] get_descendants([string]$path){
    <#
    Get all items in the specified directory, and recursively traverse all descendant folders.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $sift [string] Optional, used to indicate the filtered content.
        * When the parameter value is' file', only the absolute path of the files in it will be returned.
        * When the parameter value is' folder', the absolute path of the directory (folder) in it is returned.
    #>
    $ary = [ArrayList]::new();
    $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
    foreach ($item in $item_obj){
        if([Path]::is_dirname($item)){
            $sub_ary = [Path]::get_descendants($item);
            $ary.AddRange($sub_ary);
        }
        else{
            $ary.Add($item);
        }
    }
    return $ary
}
static [string[]] get_descendants([string]$path, [string]$sift){
    $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
    $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
    $ary = [ArrayList]::new()
    # only file
    if($sift -eq 'file'){
        if($null -ne $files){
            foreach ($file in $files){
                $ary.Add($file)
            }
        }
        foreach ($item in $folders){
            $ary.AddRange([Path]::get_descendants($item,'file'))
        }
    }
    # only dir
    elseif ($sift -eq 'folder') {
        if($null -ne $folders){
            foreach ($item in $folders){
                $ary.Add($item);
                $ary.AddRange([Path]::get_descendants($item,'folder'))
            }
        }
    }
    # all
    else{
        $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
        foreach ($item in $item_obj){
            if([Path]::is_dirname($item)){
                $sub_ary = [Path]::get_descendants($item);
                $ary.AddRange($sub_ary);
            }
            else{
                $ary.Add($item);
            }
        }
    }
    return $ary
}

【例如】:

方法 get_descendants 与方法 get_items 的区别在于, get_descendants的查找范围不限于其自身,还包括其所有的子孙目录。

10. 在指定目录下筛选文件

static [string[]]filter_files([string]$path, [string]$sub_string){
    <#
    Filter the files containing the specified string from the specified directory.
    Params
    ======
    - $path [string] 
    - $sub_string [string] 
    - $recursion [bool] Recursively search all descendant directories, defaulf $False
    #>
    $ary = [ArrayList]::new();
    foreach ($item in [Path]::get_items($path,'file')) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}
static [string[]]filter_files([string]$path, [string]$sub_string, [bool]$recursion){
    $ary = [ArrayList]::new();
    if($recursion){
        $all = [Path]::get_descendants($path,'file')
    }else{
        $all = [Path]::get_items($path,'file')
    }
    foreach ($item in $all) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}

【例如】:

11. 在指定目录下筛选目录

static [string[]]filter_dirs([string]$path, [string]$sub_string){
    $ary = [ArrayList]::new();
    foreach ($item in [Path]::get_items($path,'folder')) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}
static [string[]]filter_dirs([string]$path, [string]$sub_string, [bool]$recursion){
    $ary = [ArrayList]::new();
    if($recursion){
        $all = [Path]::get_descendants($path,'folder')
    }else{
        $all = [Path]::get_items($path,'folder')
    }
    foreach ($item in $all) {
        if([Path]::basename($item).Contains($sub_string)){
            $ary.Add($item)
        }
    }
    return $ary
}

【例如】:

12. 获取文件或者目录的修改时间

static [System.DateTime]get_modify_time([string]$path){
    <#
    Returns the last modification time of a file or directory.
    Params
    ======
    - $path [string] The path value represented by a string.
    #>
    return [System.IO.DirectoryInfo]::new($path).LastWriteTime
}

【例如】:

13. 判断指定路径是否实际是一个文件夹

static [bool]is_dirname([string]$path){
    <#
    Specifies whether the path represents a folder.
    Params
    ======
    - $path [string] The path value represented by a string.
    Returns
    =======
        - $True  If the specified path represents a folder
        - $False Versa
    Notes
    =====
        In most cases, you can also use the command: 
        `Test-Path -Path $path -PathType leaf `, 
        However, using the `Test-Path` command can't deal with 
        the case that the file name contains "[" as the powershell 
        compiler will throw back an error in this case.
    #>
    return [Path]::has_attributes($path,"Directory")
}

【例如】:

14. 判断指定路径是否实际是一个文件

static [bool]is_filename([string]$path){
    <#
    Returns whether the specified path value represents a file.
    Params
    ======
    - $path The path value represented by a string.
    Notes
    =====
        In most cases, you can also use the command: 
        `Test-Path -Path $path -PathType leaf `, 
        However, using the `Test-Path` command can't deal with 
        the case that the file name contains "[" as the powershell 
        compiler will throw back an error in this case.
    #>
    return -not [Path]::has_attributes($path,"Directory")
}

【例如】:

15. 判断文件是否比指定日期新

static [bool]is_newer_than($path, $time){
    <#
    Test whether the time of a file is before the specified date.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $time A point-in-time string, such as "July 13, 2009"
    Returns
    =======
    - $True  If the modification time of the specified file is newer than this point in time;
    - $False Versa。
    #>
    return Test-Path -Path $path -NewerThan $time
}

该方法仅适用于文件系统驱动器。

【例如】:

16. 判断目录是否为空

static [bool]is_empty([string]$path){
    <#
    The folder is not empty, or the specified path is a file.
    Params
    ======
    - $path [string] The path value represented by a string.
    Retuens
    =======
    - $True  Folder is empty.
    - $False The folder is not empty, or the specified path is a file.
    #>
    if([Path]::is_dirname($path)){
        if((Get-ChildItem $path).count -eq 0){
            return $True
        }
        else{
            return $False
        }
    }
    else{
        write-host -ForegroundColor Yellow "Warning: The actual parameter of the variable `$path is a file name while a folder name is expected. "
        return $False
    }
}

【例如】:

17. 判断某个路径值是否为绝对路径

static [bool]is_abs([string]$path){
    <# 
    Determine whether the path value represents an absolute path.
    Params
    ======
    - $path [string] The path value represented by a string.
    Retuens
    =======
    - $True  Is an absolute path.
    - $False Versa.
    #>
    return Split-Path -Path $path -IsAbsolute
}

【例如】:

18. 获取目录的属性描述符

static [string[]]get_attributes([string]$path){
    <#
    Gets the operator of attribute description of the directory.
    #>
    return [System.IO.File]::GetAttributes($path).ToString().Split(", ")
}

【例如】:

【又如】:

19. 判断是否包含某个属性描述符

static [bool]has_attributes([string]$path, [string]$attributes){
    <#
    Returns whether the file or directory contains an attribute descriptor.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $attributes [string] Represents an attribute descriptor of a directory. 
    Retuens
    =======
    - $True  Includes.
    - $False Not includes.
    #>
    return [Path]::get_attributes($path).Contains($attributes)
}

【其中】:

$attributes 的值可以是:

描述
Archive 此文件标记为包含在增量备份操作中。 每当修改文件时,Windows 会设置该属性,并且在增量备份期间处理文件时,备份软件应进行清理该属性。
Compressed 此文件是压缩文件。
Device 留待将来使用。
Directory 此文件是一个目录。 Directory 在 Windows、Linux 和 macOS 上受支持。
Encrypted 此文件或目录已加密。 对于文件来说,表示文件中的所有数据都是加密的。 对于目录来说,表示新创建的文件和目录在默认情况下是加密的。
Hidden 文件是隐藏的,因此没有包括在普通的目录列表中。 Hidden 在 Windows、Linux 和 macOS 上受支持。
IntegrityStream 文件或目录包括完整性支持数据。 在此值适用于文件时,文件中的所有数据流具有完整性支持。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应包括完整性支持。
Normal 该文件是没有特殊属性的标准文件。 仅当其单独使用时,此特性才有效。 Normal 在 Windows、Linux 和 macOS 上受支持。
NoScrubData 文件或目录从完整性扫描数据中排除。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应不包括数据完整性。
NotContentIndexed 将不会通过操作系统的内容索引服务来索引此文件。
Offline 此文件处于脱机状态, 文件数据不能立即供使用。
ReadOnly 文件为只读文件。 ReadOnly 在 Windows、Linux 和 macOS 上受支持。 在 Linux 和 macOS 上,更改 ReadOnly 标记是权限操作。
ReparsePoint 文件包含一个重新分析点,它是一个与文件或目录关联的用户定义的数据块。 ReparsePoint 在 Windows、Linux 和 macOS 上受支持。
SparseFile 此文件是稀疏文件。 稀疏文件一般是数据通常为零的大文件。
System 此文件是系统文件。 即,该文件是操作系统的一部分或者由操作系统以独占方式使用。
Temporary 文件是临时文件。 临时文件包含当执行应用程序时需要的,但当应用程序完成后不需要的数据。 文件系统尝试将所有数据保存在内存中,而不是将数据刷新回大容量存储,以便可以快速访问。 当临时文件不再需要时,应用程序应立即删除它。

【例如】:

可以知道,该文件是一个具有 Hidden的文件(隐藏文件)。

20. 计算文件或目录的大小

static [int64]$counter;
static [int64]get_size([string]$path){
    <#
    Returns the file size, or an error if the file does not exist.
    Params
    ======
    - $path [string] The path value represented by a string.
    #>
    [Path]::counter = -1;
    return [Path]::get_size($path,[Path]::counter)
}
static [int64]get_size([string]$path,[string]$ParentId){
    $count_size = 0;
    $file_infos = Get-ChildItem $path;
    # If it is a file, directly return the file size.
    if($file_infos.Attribute -eq 'Archive'){
        write-host $path+" is a file."
        $count_size = $count_size + $file_infos.Length;
    }
    # If it is a directory, the total size is calculated recursively.
    else{
        $count = $file_infos.Count;
        for ($i = 0; $i -lt $file_infos.Count; $i++) {
            $child = $file_infos[$i];
            [Path]::counter = [Path]::counter+1; # Each one is assigned an ID separately.
            $ID = [Path]::counter;
            # If it is a file, the size is accumulated.
            if([Path]::is_filename($child)){
                $count_size =  $count_size + $child.Length;
            }
            # If it is a directory, continue to recursively accumulate the size.
            else{
                $count_size =  $count_size + [Path]::get_size($child,$ID)
            }
            # 进度条显示
            $percent = $i / $count;  # 以子条目计算百分比
            if($ParentId -eq -1){
                Write-Progress -ID $ID -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
            }else{
                Write-Progress -ID $ID -ParentId $ParentId -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
            }
        }
    }
    return $count_size
}

【例如】:

21. 连结路径

static [string]join($path, $childpath){
    <# 
    Connect the directory and file name into a path.
    Params
    ======
    - $path [string] The path value represented by a string.
    - $childpath [string] childpath path value represented by a string.
    #>
    return Join-Path -Path $path -ChildPath $childpath
}

【例如】:

22. 拆分路径

static [string[]]split([string]$path){
    <#
    Divide the path into two parts: dirname and basename.
    Params
    ======
    - path [string] The path value represented by a string.
    Returns
    =======
    - $dirname   The absolute path of the folder.
    - $basename  Subfile or subdirectory name
    #>
    $dirname = Split-Path -Path $path -Leaf;
    $basename = Split-Path -Path $path;
    return $dirname,$basename
}

【例如】:

23. 创建目录

static [void]make($path){
    <#
    Create a series of folders according to the given path.
    Params
    ======
    - path [string] The path value represented by a string.
    #>
    New-Item -Path ([Path]::dirname($path, $True)) -Name ([Path]::basename($path)) -ItemType "directory" 
}

【例如】:

其中

  • 如果目录完全存在,则会提示错误 "An item with the specified name XXX already exists",例如两次重复创建:
  • 如果所创建的目录的祖先文件夹都不存在,则会逐个创建祖先文件夹。

24. Path 环境变量相关方法

static [string[]]get_enviroment(){
    return [Environment]::GetEnvironmentVariable('Path', 'Machine')
}
static [void]set_enviroment($path){
    [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
}
static [void]set_enviroment($path,$env_var_target){
    if($env_var_target -eq 'Machine'){
        [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
    }
    elseif($env_var_target -eq 'User'){
        [Environment]::SetEnvironmentVariable('Path', $path,'User')
    }
    else{
        write-host -ForegroundColor Red "ValueError: The value of variable  `"`$env_var_target`" can only be one of 'Machine' or 'User'." 
    }   
}

【例如】:


         

25. 删除路径对应的项目

static [void] delete([string]$path){
    <#
    Delete the file or directory corresponding to the specified path.
    Params
    ======
    - path [string] The path value represented by a string.
    #>
    Remove-Item $path;
}

【例如】:


         

附录: Path类代码

<#
@Auth: Jack Lee;
@Email: 291148484@163.com;
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#>
using namespace System;
using namespace System.Collections;
using namespace System.Collections.Generic;
class Path{
    static [string]abspath([string]$path){
        <#
        Return absolute path
        Params
        ======
        - $path [string] Path of file.
        #>
        return Resolve-Path -Path $path; 
    }
    static [string]basename([string]$path){
        <#
        Returns the file name from the absolute path value represented by a string.
        Params
        ======
        - $path [string] The absolute path of the file.
        - $extension [bool] Whether to remove the extension.
        #>
        return  [System.IO.Path]::GetFileName($path)
    }
    static [string]basename([string]$path,[bool]$extension=$True){
        if($extension){
            return  [System.IO.Path]::GetFileName($path)
        }
        else{
            return [System.IO.Path]::GetFileNameWithoutExtension($path)
        }
    }
    static [string]rootname([string]$path){
        <# Return root directory information #>
        return [System.IO.Path]::GetPathRoot($path)
    }
    static [string]get_temp_path(){
        <# Returns the path of the current system temporary directory. #>
        return [System.IO.Path]::GetTempPath()
    }
    static [string]get_dirpath([string]$path){
        <#
        Returns the absolute path of the parent folder.
        Params
        ======
        - $path [string] Represents the absolute path of a file.
        #>
      return [System.IO.Path]::GetDirectoryName($path)
  }
    static [string]get_dirname([string]$path){
        <#
        Returns the name of the folder where the file or subfolder is located.
        Params
        ======
        - $path [string] Represents the absolute path of a file.
        #>
        return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
    }
    static [string]get_dirname([string]$path, [bool]$absolute=$True){
        if($absolute){
            return [System.IO.Path]::GetDirectoryName($path)
        }
        else{
            return [Path]::basename([System.IO.Path]::GetDirectoryName($path))
        }
    }
    static [bool] exists([string]$path){
        <#
        Determine whether the specified file or directory exists.
        Params
        ======
        - $path [string] The path value represented by a string.
        Returns
        =======
        - $True  exist.
        - $False non-existent.
        #>
        return Test-Path -Path $path
    }
    static [string]relpath([string]$relativeTo, [string]$path){
        <#
        Returns the relative path from one path to another.
        Params
        ======
        - $relativeTo [string] The source path relative to the result. This path is always treated as a directory.
        - $path [string] Target path.
        Returns
        =======
        [string] Relative path, or path if the paths do not share the same root.
        Exceptions
        ==========
        - [ArgumentNullException] The value of $relativeTo or $path is null。
        - [ArgumentException] $relativeTo or $path is actually null.
        #>
        return [System.IO.Path]::GetRelativePath($relativeTo, $path)
    }
    static [string[]] get_items([string]$path){
        <#
        Get all subprojects in the specified directory. 
        Params
        ======
        - $path [string] The path value represented by a string.
        - $sift [string] Optional, used to indicate the filtered content.
          * When the parameter value is' file', only the absolute path of 
            the files in it will be returned.
          * When the parameter value is' folder', the absolute path of the 
            directory (folder) in it is returned.
        Notes
        =====
          This method only gets the current level of subdirectories, while 
          the folders containing subdirectories will not be traversed.
          If you need to recursively obtain all descendants directories, 
          you should consider using `get_descendants()` method instead.
        #>
        $item_obj = Get-ChildItem $path |  Sort-Object
        $ary = [ArrayList]::new()
        foreach ($item in $item_obj){
            $ary.Add($item.ToString())
        }
        return $ary
    }
    static [string[]] get_items([string]$path, [string]$sift){
        if($sift -eq 'file'){
            $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
            $ary = [ArrayList]::new()
            foreach ($item in $files){
                $ary.Add($item.ToString())
            }
            return $ary
        }elseif ($sift -eq 'folder') {
            $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
            $ary = [ArrayList]::new()
            foreach ($item in $folders){
                $ary.Add($item.ToString())
            }
            return $ary
        }else{
            $item_obj = Get-ChildItem $path |  Sort-Object
            $ary = [ArrayList]::new()
            foreach ($item in $item_obj){
                $ary.Add($item.ToString())
            }
            return $ary
        }
    }
    static [string[]] get_descendants([string]$path){
        <#
        Get all items in the specified directory, and recursively traverse all descendant folders.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $sift [string] Optional, used to indicate the filtered content.
          * When the parameter value is' file', only the absolute path of the files in it will be returned.
          * When the parameter value is' folder', the absolute path of the directory (folder) in it is returned.
        #>
        $ary = [ArrayList]::new();
        $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
        foreach ($item in $item_obj){
            if([Path]::is_dirname($item)){
                $sub_ary = [Path]::get_descendants($item);
                $ary.AddRange($sub_ary);
            }
            else{
                $ary.Add($item);
            }
        }
        return $ary
    }
    static [string[]] get_descendants([string]$path, [string]$sift){
        $files = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $False} | Sort-Object;
        $folders = Get-ChildItem $path | Where-Object {$_.PSIsContainer -eq $True} | Sort-Object;
        $ary = [ArrayList]::new()
        # only file
        if($sift -eq 'file'){
            if($null -ne $files){
                foreach ($file in $files){
                    $ary.Add($file)
                }
            }
            foreach ($item in $folders){
                $ary.AddRange([Path]::get_descendants($item,'file'))
            }
        }
        # only dir
        elseif ($sift -eq 'folder') {
            if($null -ne $folders){
                foreach ($item in $folders){
                    $ary.Add($item);
                    $ary.AddRange([Path]::get_descendants($item,'folder'))
                }
            }
        }
        # all
        else{
            $item_obj = Get-ChildItem $path |  Sort-Object; # current directory
            foreach ($item in $item_obj){
                if([Path]::is_dirname($item)){
                    $sub_ary = [Path]::get_descendants($item);
                    $ary.AddRange($sub_ary);
                }
                else{
                    $ary.Add($item);
                }
            }
        }
        return $ary
    }
    static [string[]]filter_files([string]$path, [string]$sub_string){
        <#
        Filter the files containing the specified string from the specified directory.
        Params
        ======
        - $path [string] 
        - $sub_string [string] 
        - $recursion [bool] Recursively search all descendant directories, defaulf $False
        #>
        $ary = [ArrayList]::new();
        foreach ($item in [Path]::get_items($path,'file')) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_files([string]$path, [string]$sub_string, [bool]$recursion){
        $ary = [ArrayList]::new();
        if($recursion){
            $all = [Path]::get_descendants($path,'file')
        }else{
            $all = [Path]::get_items($path,'file')
        }
        foreach ($item in $all) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_dirs([string]$path, [string]$sub_string){
        $ary = [ArrayList]::new();
        foreach ($item in [Path]::get_items($path,'folder')) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [string[]]filter_dirs([string]$path, [string]$sub_string, [bool]$recursion){
        $ary = [ArrayList]::new();
        if($recursion){
            $all = [Path]::get_descendants($path,'folder')
        }else{
            $all = [Path]::get_items($path,'folder')
        }
        foreach ($item in $all) {
            if([Path]::basename($item).Contains($sub_string)){
                $ary.Add($item)
            }
        }
        return $ary
    }
    static [System.DateTime]get_modify_time([string]$path){
        <#
        Returns the last modification time of a file or directory.
        Params
        ======
        - $path [string] The path value represented by a string.
        #>
        return [System.IO.DirectoryInfo]::new($path).LastWriteTime
    }
    static [bool]is_dirname([string]$path){
        <#
        Specifies whether the path represents a folder.
        Params
        ======
        - $path [string] The path value represented by a string.
        Returns
        =======
         - $True  If the specified path represents a folder
         - $False Versa
        Notes
        =====
          In most cases, you can also use the command: 
          `Test-Path -Path $path -PathType leaf `, 
          However, using the `Test-Path` command can't deal with 
          the case that the file name contains "[" as the powershell 
          compiler will throw back an error in this case.
        #>
        return [Path]::has_attributes($path,"Directory")
    }
    static [bool]is_filename([string]$path){
        <#
        Returns whether the specified path value represents a file.
        Params
        ======
        - $path The path value represented by a string.
        Notes
        =====
          In most cases, you can also use the command: 
          `Test-Path -Path $path -PathType leaf `, 
          However, using the `Test-Path` command can't deal with 
          the case that the file name contains "[" as the powershell 
          compiler will throw back an error in this case.
        #>
        return -not [Path]::has_attributes($path,"Directory")
    }
    static [bool]is_newer_than($path, $time){
        <#
        Test whether the time of a file is before the specified date.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $time A point-in-time string, such as "July 13, 2009"
        Returns
        =======
        - $True  If the modification time of the specified file is newer than this point in time;
        - $False Versa。
        #>
        return Test-Path -Path $path -NewerThan $time
    }
    static [bool]is_empty([string]$path){
        <#
        The folder is not empty, or the specified path is a file.
        Params
        ======
        - $path [string] The path value represented by a string.
        Retuens
        =======
        - $True  Folder is empty.
        - $False The folder is not empty, or the specified path is a file.
        #>
        if([Path]::is_dirname($path)){
            if((Get-ChildItem $path).count -eq 0){
                return $True
            }
            else{
                return $False
            }
        }
        else{
            write-host -ForegroundColor Yellow "Warning: The actual parameter of the variable `$path is a file name while a folder name is expected. "
            return $False
        }
    }
    static [bool]is_abs([string]$path){
        <# 
        Determine whether the path value represents an absolute path.
        Params
        ======
        - $path [string] The path value represented by a string.
        Retuens
        =======
        - $True  Is an absolute path.
        - $False Versa.
        #>
        return Split-Path -Path $path -IsAbsolute
    }
    static [string[]]get_attributes([string]$path){
        <#
        Gets the operator of attribute description of the directory.
        #>
        return [System.IO.File]::GetAttributes($path).ToString().Split(", ")
    }
    static [bool]has_attributes([string]$path, [string]$attributes){
        <#
        Returns whether the file or directory contains an attribute descriptor.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $attributes [string] Represents an attribute descriptor of a directory. The value of $attributes could be:
            * Archive 此文件标记为包含在增量备份操作中。 每当修改文件时,Windows 会设置该属性,并且在增量备份期间处理文件时,备份软件应进行清理该属性。
            * Compressed 此文件是压缩文件。
            * Device 留待将来使用。
            * Directory 此文件是一个目录。 Directory 在 Windows、Linux 和 macOS 上受支持。
            * Encrypted 此文件或目录已加密。 对于文件来说,表示文件中的所有数据都是加密的。 对于目录来说,表示新创建的文件和目录在默认情况下是加密的。
            * Hidden 文件是隐藏的,因此没有包括在普通的目录列表中。 Hidden 在 Windows、Linux 和 macOS 上受支持。
            * IntegrityStream 文件或目录包括完整性支持数据。 在此值适用于文件时,文件中的所有数据流具有完整性支持。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应包括完整性支持。
            * Normal 该文件是没有特殊属性的标准文件。 仅当其单独使用时,此特性才有效。 Normal 在 Windows、Linux 和 macOS 上受支持。
            * NoScrubData 文件或目录从完整性扫描数据中排除。 此值将应用于一个目录时,所有新文件和子目录在该目录中和默认情况下应不包括数据完整性。
            * NotContentIndexed 将不会通过操作系统的内容索引服务来索引此文件。
            * Offline 此文件处于脱机状态, 文件数据不能立即供使用。
            * ReadOnly 文件为只读文件。 ReadOnly 在 Windows、Linux 和 macOS 上受支持。 在 Linux 和 macOS 上,更改 ReadOnly 标记是权限操作。
            * ReparsePoint 文件包含一个重新分析点,它是一个与文件或目录关联的用户定义的数据块。 ReparsePoint 在 Windows、Linux 和 macOS 上受支持。
            * SparseFile 此文件是稀疏文件。 稀疏文件一般是数据通常为零的大文件。
            * System 此文件是系统文件。 即,该文件是操作系统的一部分或者由操作系统以独占方式使用。
            * Temporary 文件是临时文件。 临时文件包含当执行应用程序时需要的,但当应用程序完成后不需要的数据。 文件系统尝试将所有数据保存在内存中,而不是将数据刷新回大容量存储,以便可以快速访问。 当临时文件不再需要时,应用程序应立即删除它。
        Retuens
        =======
        - $True  Includes.
        - $False Not includes.
        #>
        return [Path]::get_attributes($path).Contains($attributes)
    }
    static [int64]$counter;
    static [int64]get_size([string]$path){
        <#
        Returns the file size, or an error if the file does not exist.
        Params
        ======
        - $path [string] The path value represented by a string.
        #>
        [Path]::counter = -1;
        return [Path]::get_size($path,[Path]::counter)
    }
    static [int64]get_size([string]$path,[string]$ParentId){
        $count_size = 0;
        $file_infos = Get-ChildItem $path;
        # If it is a file, directly return the file size.
        if($file_infos.Attribute -eq 'Archive'){
            write-host $path+" is a file."
            $count_size = $count_size + $file_infos.Length;
        }
        # If it is a directory, the total size is calculated recursively.
        else{
            $count = $file_infos.Count;
            for ($i = 0; $i -lt $file_infos.Count; $i++) {
                $child = $file_infos[$i];
                [Path]::counter = [Path]::counter+1; # Each one is assigned an ID separately.
                $ID = [Path]::counter;
                # If it is a file, the size is accumulated.
                if([Path]::is_filename($child)){
                    $count_size =  $count_size + $child.Length;
                }
                # If it is a directory, continue to recursively accumulate the size.
                else{
                    $count_size =  $count_size + [Path]::get_size($child,$ID)
                }
                # Progress bar display
                $percent = $i / $count;  # Calculate the percentage by subentry.
                if($ParentId -eq -1){
                    Write-Progress -ID $ID -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
                }else{
                    Write-Progress -ID $ID -ParentId $ParentId -Activity ("Total counts "+$count.ToString()+"bytes of path: "+$child.ToString()) -Status "$percent% completed." -PercentComplete $percent;
                }
            }
        }
        return $count_size
    }
    static [string]join($path, $childpath){
        <# 
        Connect the directory and file name into a path.
        Params
        ======
        - $path [string] The path value represented by a string.
        - $childpath [string] childpath path value represented by a string.
        #>
        return Join-Path -Path $path -ChildPath $childpath
    }
    static [string[]]split([string]$path){
        <#
        Divide the path into two parts: dirname and basename.
        Params
        ======
        - path [string] The path value represented by a string.
        Returns
        =======
        - $dirname   The absolute path of the folder.
        - $basename  Subfile or subdirectory name
        #>
        $dirname = Split-Path -Path $path -Leaf;
        $basename = Split-Path -Path $path;
        return $dirname,$basename
    }
    static [string[]]get_enviroment(){
        return [Environment]::GetEnvironmentVariable('Path', 'Machine')
    }
    static [void]set_enviroment($path){
        [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
    }
    static [void]set_enviroment($path,$env_var_target){
        if($env_var_target -eq 'Machine'){
            [Environment]::SetEnvironmentVariable('Path', $path,'Machine')
        }
        elseif($env_var_target -eq 'User'){
            [Environment]::SetEnvironmentVariable('Path', $path,'User')
        }
        else{
            write-host -ForegroundColor Red "ValueError: The value of variable  `"`$env_var_target`" can only be one of 'Machine' or 'User'." 
        }   
    }
    static [void]delete([string]$path){
        <#
        Delete the file or directory corresponding to the specified path.
        Params
        ======
        - path [string] The path value represented by a string.
        #>
        Remove-Item $path;
    }
    static [void]make($path){
        <#
        Create a series of folders according to the given path.
        Params
        ======
        - path [string] The path value represented by a string.
        #>
        New-Item -Path ([Path]::dirname($path, $True)) -Name ([Path]::basename($path)) -ItemType "directory" 
    }
}

附录2: 脚本位置

方式一: Get-Location

你可以使用如下方式获取脚本所在目录的位置:

(Get-Location).Path

当你使用一个bat来调用一个包含这种方式作为BASE_DIR来使用时往往是正确的,但是如果你将这个样的bat添加到Windwos任务计划中,BASE_DIR将成为cmd.exe所在文件夹。

方式二: 使用$MyInvocation

你可以通过以下方式在ps1脚本中表示自己的脚本所在位置:

$MyInvocation.MyCommand.source

因此脚本所在文件夹的绝对路径所在位置可以表示为:

using module .\utils\jcpath.psm1
[Path]::get_dirpath($MyInvocation.MyCommand.source)
目录
相关文章
|
17天前
|
运维
【运维基础知识】用dos批处理批量替换文件中的某个字符串(本地单元测试通过,部分功能有待优化,欢迎指正)
该脚本用于将C盘test目录下所有以t开头的txt文件中的字符串“123”批量替换为“abc”。通过创建批处理文件并运行,可实现自动化文本替换,适合初学者学习批处理脚本的基础操作与逻辑控制。
115 56
|
3月前
|
数据采集 运维 Devops
探索Python编程之美:从基础到进阶自动化运维的变革之路:从脚本到DevOps
【8月更文挑战第30天】在数字化时代的浪潮中,编程已经成为一门重要的技能。Python以其简洁明了的语法和强大的功能,成为了许多初学者的首选编程语言。本文将通过浅显易懂的语言,带领读者从Python的基础语法出发,逐步深入到面向对象编程、网络爬虫开发以及数据分析等高级应用,旨在帮助初学者构建扎实的编程基础,并激发他们进一步探索编程世界的热情。文章不仅分享实用的编程技巧,还将探讨如何将编程知识应用于解决实际问题,以期培养读者的问题解决能力和创新思维。
|
3月前
|
存储 JSON JavaScript
|
3月前
PowerShell快速修改多个文件的名称
【8月更文挑战第28天】在PowerShell中批量重命名文件可通过以下方法实现:1)使用`Rename-Item`命令逐一重命名;2)通过循环批量处理特定模式的文件名更改;3)利用正则表达式进行复杂模式匹配与替换。操作前请确保验证命令并备份文件。
192 1
|
3月前
|
机器学习/深度学习 运维 Ubuntu
自动化运维:使用Ansible简化日常任务探索Python编程之美:从基础到进阶
【8月更文挑战第28天】在快速迭代的软件开发周期中,运维工作的效率至关重要。本文将介绍如何使用Ansible这一强大的自动化工具来简化日常的运维任务,通过代码示例展示如何配置和使用Ansible,以及它如何帮助提升工作效率和减少人为错误。文章将深入讨论Ansible的核心概念,包括Playbooks和Tasks,并探讨如何利用这些概念进行高效的系统管理。 【8月更文挑战第28天】在数字时代的浪潮中,编程已成为一门艺术和科学。本文将通过Python语言的镜头,带领读者踏上一段从零基础到熟练运用的旅程。我们将一起探索Python的简洁语法、强大库支持以及它在数据科学、网络开发等领域的应用。无论你
|
3月前
|
Ubuntu Linux 测试技术
【Azure Function App】Python Function调用Powershell脚本在Azure上执行失败的案例
【Azure Function App】Python Function调用Powershell脚本在Azure上执行失败的案例
|
3月前
【Azure Developer】使用PowerShell Where-Object方法过滤多维ArrayList时候,遇见的诡异问题 -- 当查找结果只有一个对象时,返回结果修改了对象结构,把多维变为一维
【Azure Developer】使用PowerShell Where-Object方法过滤多维ArrayList时候,遇见的诡异问题 -- 当查找结果只有一个对象时,返回结果修改了对象结构,把多维变为一维
|
4月前
|
SQL Rust 算法
开发与运维编程问题之常见的编程范式的声明式编程如何解决
开发与运维编程问题之常见的编程范式的声明式编程如何解决
|
4月前
|
运维
开发与运维编程问题之命令式编程的优点如何解决
开发与运维编程问题之命令式编程的优点如何解决
|
4月前
|
运维
开发与运维编程问题之常见的编程范式的响应式编程如何解决
开发与运维编程问题之常见的编程范式的响应式编程如何解决